From 6950f003dc95fb830ebb145f8b49ca30794a5cd0 Mon Sep 17 00:00:00 2001 From: Leszek Zalewski Date: Wed, 30 Sep 2026 13:49:36 +0200 Subject: [PATCH 1/3] Align documentation with code --- README.md | 110 ++++++++-- benchmark/README.md | 70 ++++++- benchmark/ghostferry_benchmark.rb | 8 +- benchmark/studies/batch_size.rb | 2 +- config.go | 86 ++++---- docs/_config.yml | 4 + docs/_plugins/changelog.rb | 20 ++ docs/_static/ghostferry-architecture.png | Bin 197633 -> 0 bytes docs/changelog.md | 3 + docs/copydbinprod.md | 176 ++++++++++------ docs/copydbinterruptresume.md | 182 +++++++++-------- docs/howtousecustom.md | 65 +++--- docs/index.md | 4 +- docs/introduction.md | 13 +- docs/technicaloverview.md | 150 +++++++++----- docs/tutorialcopydb.md | 246 ++++++++++++++--------- docs/verifiers.md | 141 ++++++++----- error_handler.go | 6 +- examples/copydb/conf.json | 9 +- filter.go | 6 +- verifier.go | 5 +- 21 files changed, 878 insertions(+), 428 deletions(-) create mode 100644 docs/_plugins/changelog.rb delete mode 100644 docs/_static/ghostferry-architecture.png create mode 100644 docs/changelog.md diff --git a/README.md b/README.md index 446ceb454..62e036c28 100644 --- a/README.md +++ b/README.md @@ -15,15 +15,19 @@ database from one machine to another. Talk to us on IRC at [irc.freenode.net #ghostferry](https://webchat.freenode.net/?channels=#ghostferry). - **Tutorial and General Documentations**: https://shopify.github.io/ghostferry -- Code documentations: https://godoc.org/github.com/Shopify/ghostferry +- Code documentations: https://pkg.go.dev/github.com/Shopify/ghostferry + (versioned API docs; for guides tracking `main`, the source in this + repository is authoritative) Overview of How it Works ------------------------ -An overview of Ghostferry's high-level design is expressed in the [TLA+ -specification](https://en.wikipedia.org/wiki/TLA%2B), under the `tlaplus` directory. It may be good to consult with -that as it has a concise definition. However, the specification might not be -entirely correct as proofs remain elusive. +A simplified model of Ghostferry's high-level copy algorithm is written in +[TLA+](https://en.wikipedia.org/wiki/TLA%2B) under the `tlaplus` directory, +together with a TLC model configuration in `tlaplus/ghostferry.toolbox`. It is +a small finite model with explicitly stated simplifying assumptions (see the +comment at the top of `tlaplus/ghostferry.tla`); model checking it is not a +proof of correctness of the current Go implementation. On a high-level, Ghostferry is broken into several components, enabling it to copy data. This is documented at @@ -52,34 +56,100 @@ The build writes the site to `build/docs/`; `htmlproofer` fails on broken internal links or anchors. The live preview is served at http://127.0.0.1:4000/ghostferry/main/. None of these commands deploy anything. +The [Changelog](docs/changelog.md) page is populated at build time from the +root `CHANGELOG.md`, which is the only file to edit for release notes; +`docs/changelog.md` is just a landing page for readers browsing the source on +GitHub. Build and serve with the commands above. The Jekyll watcher only +watches `docs/`, so restart `dev docs` / `jekyll serve` after editing the root +`CHANGELOG.md`. + Development Setup ----------------- ### Installation +#### Prerequisites + +- Go 1.26.2 (the `go` directive in `go.mod` is authoritative), Git, Make and + a MySQL client, to build and run `ghostferry-copydb`. +- For the tests and the documentation site additionally: Ruby 3.4.8 + (`.ruby-version`), Bundler 4.0.10 (`Gemfile.lock`), a C compiler toolchain + and the MySQL client development libraries needed to compile the `mysql2` + gem. Run `bundle install` without excluding the test, development or docs + groups; `test/test_helper.rb` loads `pry-byebug` from the development group + unless `CI` is set. +- Docker (or Podman with `podman-compose`) for the local MySQL servers. + +`shell.nix` is legacy: it still selects Go 1.18 and Ruby 2.7 and is not a +supported setup. + #### For Internal Contributors `dev up` #### For External Contributors -- Have Docker installed -- Clone the repo -- `docker-compose up -d` -- `nix-shell` +Start two disposable MySQL 8.0 servers from the repository root: + +```sh +docker compose -f docker-compose_8.0.yml up -d mysql-1 mysql-2 +# or: podman-compose -f docker-compose_8.0.yml up -d mysql-1 mysql-2 +``` + +They listen on ports 29291 (source) and 29292 (target) with a passwordless +`root` account. They are throwaway test servers, not a template for production +credentials. Wait until both accept connections: + +```sh +mysql --protocol=tcp -u root -P 29291 -e 'SELECT 1' +mysql --protocol=tcp -u root -P 29292 -e 'SELECT 1' +``` + +Build `ghostferry-copydb` into the first `GOPATH` entry's `bin` directory: + +```sh +export GOPATH="$(go env GOPATH)" +export PATH="${GOPATH%%:*}/bin:$PATH" +make copydb +``` + +Run the binary from the repository root: its web UI templates are loaded from +`webui/` below `ControlServerConfig.WebBasedir`, which defaults to `.`. +Debian packages built by `make copydb-deb` instead compile in the base +directory `/usr/share/ghostferry` and install `webui/` beneath it; like `.` +for source builds, the base directory is the parent of `webui/`, not the +`webui` directory itself. Packaged builds are published on the project's +[GitHub Releases](https://github.com/Shopify/ghostferry/releases) page; most +of them are prereleases (see [Releasing new version](#releasing-new-version)). Testing --------------- +Export `MYSQL_VERSION=8.0` when running tests against the MySQL 8.0 servers +above. + #### Run all tests - `make test` #### Run example copydb usage -- `make copydb && ghostferry-copydb -verbose examples/copydb/conf.json` -- For a more detailed tutorial, see the - [documentation](https://shopify.github.io/ghostferry). +`examples/copydb/conf.json` copies the `abc` database created by the +[copydb tutorial](docs/tutorialcopydb.md): seed the source with the tutorial's +SQL first, and make sure the target has no `abc` tables for a fresh run. Then, +from the repository root: + +```sh +ghostferry-copydb -verbose examples/copydb/conf.json +``` + +This example uses the `Inline` verifier, binds the UI to +`127.0.0.1:8000` and adds two Custom Script buttons. It sets +`"SkipTargetVerification": true`, which disables target-write monitoring; the +tutorial intentionally keeps the protected default. + +For a more detailed walkthrough, see the +[documentation](https://shopify.github.io/ghostferry). ### Ruby Integration Tests @@ -92,19 +162,19 @@ Examples: Run all tests -`rake test` +`bundle exec rake test` Run a single file -`rake test TEST=test/integration/trivial_test.rb` +`bundle exec rake test TEST=test/integration/trivial_test.rb` or -`ruby -Itest test/integration/trivial_test.rb` +`bundle exec ruby -Itest test/integration/trivial_test.rb` Run a specific test -`DEBUG=1 ruby -Itest test/integration/trivial_test.rb -n "TrivialIntegrationTest#test_logged_query_omits_columns"` +`DEBUG=1 bundle exec ruby -Itest test/integration/trivial_test.rb -n 'TrivialIntegrationTest#test_logged_query_omits_columns'` Releasing new version --------------------- @@ -118,10 +188,12 @@ git tag --sign --message="Initial support for UUIDs as pagination keys" canary/v git push origin --tags ``` -This will create the release named by tag. +This creates a GitHub prerelease named after the tag. ### Production -Final releases are created automatically on merge to `main` branch, they will end up with `release-SHA` name. +Every push to the `main` branch creates a GitHub **prerelease** named +`release-`. -Remember to update version prior to bigger releases in `Makefile` along with updating the `CHANGELOG.md`. +Remember to update `VERSION` in `Makefile` along with the root `CHANGELOG.md` +prior to releases. diff --git a/benchmark/README.md b/benchmark/README.md index 82aca8e9c..28364aa8b 100644 --- a/benchmark/README.md +++ b/benchmark/README.md @@ -2,7 +2,73 @@ Ghostferry benchmark setup ========================== A benchmark "library" is provided with `./ghostferry_benchmark.rb`. An example -benchmark case can be seen with `./studies/batch_size.rb` and the post -processing is provided in `./studies/batch_size_vs_row_size.ipynb`. +benchmark case can be seen with `./studies/batch_size.rb`, which measures the +copy speed for several row sizes and batch sizes. Some modifications are needed to make this benchmark work for other studies. + +Prerequisites +------------- + +Follow the Development Setup in the repository's [README](../README.md): + +- Start the local MySQL 8.0 servers from the repository root: + + ```sh + docker compose -f docker-compose_8.0.yml up -d mysql-1 mysql-2 + # or: podman-compose -f docker-compose_8.0.yml up -d mysql-1 mysql-2 + ``` + + The harness connects to them as passwordless `root` on ports 29291 (source) + and 29292 (target). + + **Warning:** the harness drops and recreates the `benchmark` schema on the + source and drops it on the target. Only point it at disposable servers. + +- Build `ghostferry-copydb` and put it on your `PATH`; the harness runs the + `ghostferry-copydb` found there: + + ```sh + export GOPATH="$(go env GOPATH)" + export PATH="${GOPATH%%:*}/bin:$PATH" + make copydb + ``` + +- Install the gems with `bundle install`, including the test and development + groups of the root `Gemfile` (`mysql2`, `webrick`, `tqdm`). + +- Ports 8000 (the Ghostferry web UI) and 8001 (the harness's progress callback + server) must be free on 127.0.0.1. + +Running the batch size study +---------------------------- + +From the `benchmark/` directory: + +```sh +bundle exec ruby studies/batch_size.rb +``` + +For each row size, the study seeds `benchmark.t` on the source, then for each +batch size wipes the target, runs `ghostferry-copydb` for 15 seconds, stops it +and computes the average copy speed from the progress callbacks. The generated +configuration sets `ControlServerConfig.WebBasedir` to the repository root, so +the web UI is found although the study runs from `benchmark/`. + +Outputs, relative to `benchmark/`: + +- `out/rs=-bs=/conf.json`: the Ghostferry configuration; +- `out/rs=-bs=/ghostferry.log`: Ghostferry's output; +- `out/rs=-bs=/progress.json.log`: the progress callbacks; +- `out/rs=-bs=/rows_written.csv`: time taken, rows + written and state per progress callback; +- `studies/batch_size_benchmark.csv`: `row size,batch size,rows/s` per case. + +Analysis notebook +----------------- + +`studies/batch_size_vs_row_size.ipynb` analyses the checked-in historical +results in `studies/benchmark.csv`; it is not fed automatically by +`studies/batch_size.rb`. It needs Jupyter, NumPy, Matplotlib and SciPy, and must +be run with `benchmark/studies` as its working directory. To analyse new results, +change its CSV input, plot ranges and interpolation domain to match your study. diff --git a/benchmark/ghostferry_benchmark.rb b/benchmark/ghostferry_benchmark.rb index 2d1d6cf4b..34a272c27 100644 --- a/benchmark/ghostferry_benchmark.rb +++ b/benchmark/ghostferry_benchmark.rb @@ -144,7 +144,13 @@ def default_ghostferry_config "DumpStateOnSignal" => false, "VerifierType" => "Inline", "SkipTargetVerification" => true, - "DataIterationBatchSize" => 200 + "UpdatableConfig" => { + "DataIterationBatchSize" => 200 + }, + "ControlServerConfig" => { + "WebBasedir" => File.expand_path("..", __dir__), + "ServerBindAddr" => "127.0.0.1:8000" + } } end diff --git a/benchmark/studies/batch_size.rb b/benchmark/studies/batch_size.rb index df6bc9f19..5d7a5860b 100755 --- a/benchmark/studies/batch_size.rb +++ b/benchmark/studies/batch_size.rb @@ -25,7 +25,7 @@ FileUtils.mkdir_p(output_dir) config = GhostferryBenchmark.default_ghostferry_config - config["DataIterationBatchSize"] = batch_size + config["UpdatableConfig"]["DataIterationBatchSize"] = batch_size GhostferryBenchmark::Databases.wipe_target speed = GhostferryBenchmark.run_ghostferry(ghostferry_config: config, output_dir: output_dir) diff --git a/config.go b/config.go index d696b79ab..00a6dd977 100644 --- a/config.go +++ b/config.go @@ -194,8 +194,9 @@ func (c *DatabaseConfig) assertParamSet(param, value string) error { type InlineVerifierConfig struct { // The maximum expected downtime during cutover, in the format of - // time.ParseDuration. If nothing is specified, the InlineVerifier will not - // try to estimate the downtime and will always allow cutover. + // time.ParseDuration. If nothing is specified (or it is zero), the + // InlineVerifier does not enforce a downtime limit in VerifyBeforeCutover; + // verification itself still takes place. MaxExpectedDowntime string // The interval at which the periodic binlog reverification occurs, in the @@ -261,8 +262,8 @@ type IterativeVerifierConfig struct { // Optional: defaults to empty map/no compression // // Note that the IterativeVerifier is in the process of being deprecated. - // If this is specified, ColumnCompressionConfig should also be filled out in - // the main Config. + // If this is specified, CompressedColumnsForVerification should also be + // filled out in the main Config. TableColumnCompression TableColumnCompressionConfig } @@ -288,7 +289,7 @@ type ControlServerConfig struct { // Bind control server address ServerBindAddr string - // Path to `web` base dir + // Path to the directory containing the `webui` directory WebBasedir string // TODO: refactor control server config out of the base ferry at some point @@ -590,14 +591,14 @@ type Config struct { // The maximum number of retries for reads if the reads fail on the source // database. // - // Optional: defaults to 5 + // Optional: defaults to 60 DBReadRetries int - // This specify the number of concurrent goroutines, each iterating over + // This specifies the number of concurrent goroutines, each iterating over // a single table. // - // At this point in time, parallelize iteration within a single table. This - // may be possible to add to the future. + // Concurrency is across tables: a single table is always iterated by one + // goroutine and is not split among workers. // // Optional: defaults to 4 DataIterationConcurrency int @@ -607,9 +608,13 @@ type Config struct { // Optional: defaults to false AutomaticCutover bool - // This specifies whether or not Ferry.Run will handle SIGINT and SIGTERM - // by dumping the current state to stdout and the error HTTP callback. - // The dumped state can be used to resume Ghostferry. + // This specifies whether or not Ferry.Run installs a SIGINT and SIGTERM + // handler that reports the signal as a fatal error, so that the error + // handler can dump the current state for resuming Ghostferry. With the + // default error handler, the state is only written to stdout if + // DumpStateToStdoutOnError is also set (and sent to the ErrorCallback, if + // configured). A signal received during cutover is logged and ignored; a + // signal received after the run is done exits the process. DumpStateOnSignal bool // This specifies whether or not Ghostferry will dump the current state to stdout @@ -632,14 +637,14 @@ type Config struct { ProgressCallback HTTPCallback ProgressReportFrequency int - // Report state via an HTTP callback. The SerializedState struct will be - // sent as the Payload parameter. The unit of StateReportFrequency is - // in milliseconds. + // Report state via an HTTP callback. The serialized SerializableState + // (the same JSON as the state dump) will be sent as the Payload parameter. + // The unit of StateReportFrequency is in milliseconds. StateCallback HTTPCallback StateReportFrequency int - // Report error via an HTTP callback. The Payload field will contain the ErrorType, - // ErrorMessage and the StateDump. + // Report error via an HTTP callback. The Payload field will contain a JSON + // object with the ErrFrom, ErrMessage and StateDump fields. ErrorCallback HTTPCallback // Report when ghostferry is entering cutover @@ -661,13 +666,16 @@ type Config struct { // reconciliation process will start and Ghostferry will resume after that. StateToResumeFrom *SerializableState - // The verifier to use during the run. Valid choices are: + // The data verifier to use during the run. Valid choices are: // ChecksumTable - // Iterative + // Inline + // Iterative (deprecated) // NoVerification // // If it is left blank, the Verifier member variable on the Ferry will be - // used. If that member variable is nil, no verification will be done. + // used, which allows a custom verifier. If that member variable is nil, no + // verification will be done. Target verification (see + // SkipTargetVerification) is independent of this choice. VerifierType string // Only useful if VerifierType == Iterative. @@ -732,29 +740,35 @@ type Config struct { ForceIndexForVerification ForceIndexConfig // Ghostferry requires a single numeric or binary column to paginate over tables. Inferring that column is done in the following exact order: - // 1. Use the PerTable pagination column, if configured for a table. Fail if we cannot find this column in the table. - // 2. Use the table's primary key column as the pagination column. Fail if the primary key is not numeric/binary or is a composite key without a FallbackColumn specified. - // 3. Use the FallbackColumn pagination column, if configured. Fail if we cannot find this column in the table. - // - // IMPORTANT: The pagination column MUST contain unique values for data integrity. - // When using a FallbackColumn (typically "id") for tables with composite primary keys, this column must have a unique constraint. + // 1. Use the PerTable pagination column, if configured for a table. + // 2. Otherwise, use the table's primary key if it consists of a single column. + // 3. Otherwise (no primary key, or a composite primary key), use the FallbackColumn, if configured. + // Schema loading fails if no column is selected, if the selected column does not exist, or if it is not an + // integer or binary column (BINARY/VARBINARY, or CHAR/VARCHAR with a binary collation). A single-column + // primary key of an unsupported type is not replaced by the FallbackColumn; it fails. + // Numeric pagination keys must be positive integers and binary pagination keys must be non-empty, as + // pagination starts after zero/the empty value. + // + // IMPORTANT: The pagination column MUST contain unique, non-NULL values for data integrity. Ghostferry does + // not validate this; the caller is responsible for it, ideally with a unique constraint on the column. // The pagination algorithm uses WHERE pagination_key > last_key ORDER BY pagination_key LIMIT batch_size. // If duplicate values exist, rows may be skipped during iteration, resulting in data loss during the migration. CascadingPaginationColumnConfig *CascadingPaginationColumnConfig // SkipTargetVerification is used to enable or disable target verification during moves. - // This feature is currently only available while using the InlineVerifier. + // When false (the default), target verification is enabled regardless of the VerifierType. // - // This does so by inspecting the annotations (configured as Marginalia in the DatabaseConfig above) - // and will fail the move unless all applicable DMLs (as identified by the sharding key) sent to the - // Target were sent from Ghostferry. + // Target verification streams the Target's binlog and inspects the annotations (configured as Marginalia + // in the DatabaseConfig above), failing the move unless all applicable DMLs sent to the Target carry + // Ghostferry's annotation. It detects unexpected writers; it does not compare row data. // // NOTE: // The Target database must be configured with binlog_rows_query_log_events - // set to "ON" for this to function properly. Ghostferry not allow the move - // process to begin if this is enabled and the above option is set to "OFF". + // set to "ON" for this to function properly. While this is enabled, + // Ghostferry does not allow the move process to begin if the Source has + // binlog_rows_query_log_events set to "OFF". // - // Required: defaults to false + // Optional: defaults to false SkipTargetVerification bool // During initialization, Ghostferry will raise an error if any @@ -942,9 +956,9 @@ func (c *Config) Update(updatedConfig UpdatableConfig) { // UpdatableConfig defines config fields that support dynamic updates type UpdatableConfig struct { - // The batch size used to iterate the data during data copy. This batch size - // is always used: if this is specified to be 100, 100 rows will be copied - // per iteration. + // The maximum batch size used to iterate the data during data copy. A batch + // may contain fewer rows (for example the last batch of a table), and + // DataIterationBatchSizePerTableOverride can set other sizes per table. // // With the current implementation of Ghostferry, we need to lock the rows // we select. This means, the larger this number is, the longer we need to diff --git a/docs/_config.yml b/docs/_config.yml index 640a49c14..10e4daa5c 100644 --- a/docs/_config.yml +++ b/docs/_config.yml @@ -46,6 +46,8 @@ gh_edit_repository: https://github.com/Shopify/ghostferry gh_edit_branch: main gh_edit_source: docs gh_edit_view_mode: edit +# Just the Docs only renders the edit link when its text is set. +gh_edit_link_text: Edit this page on GitHub # Page titles and order live here so the Markdown files need no front matter. defaults: @@ -70,3 +72,5 @@ defaults: values: { title: Verifiers, nav_order: 7 } - scope: { path: howtousecustom.md } values: { title: Custom applications, nav_order: 8 } + - scope: { path: changelog.md } + values: { title: Changelog, nav_order: 9 } diff --git a/docs/_plugins/changelog.rb b/docs/_plugins/changelog.rb new file mode 100644 index 000000000..4bb5e9ef4 --- /dev/null +++ b/docs/_plugins/changelog.rb @@ -0,0 +1,20 @@ +# frozen_string_literal: true + +module GhostferryDocs + # Renders the repository's root CHANGELOG.md as the body of docs/changelog.md, + # so the release history is maintained in one place. Runs after + # jekyll-optional-front-matter (:normal) has loaded the page and before + # jekyll-relative-links (:lowest) rewrites links. + class ChangelogGenerator < Jekyll::Generator + priority :low + + def generate(site) + page = site.pages.find { |candidate| candidate.relative_path == "changelog.md" } + raise Jekyll::Errors::FatalException, "Changelog page docs/changelog.md was not loaded" unless page + + page.content = File.read(File.expand_path("../CHANGELOG.md", site.source), encoding: "UTF-8") + # Makes the theme's "Edit this page" link point at the root CHANGELOG.md. + page.data["path"] = "../CHANGELOG.md" + end + end +end diff --git a/docs/_static/ghostferry-architecture.png b/docs/_static/ghostferry-architecture.png deleted file mode 100644 index 0393381693cf6af402bec4e893cb6890f7f404e9..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 197633 zcmbrmcR-JQ+duxPhz2qWArfgwOCl|4Pi-nqX^Rx?(jbYXL1;-zQ?$3yP?UBmEe-9x z*Y9<@ujhI0XMF$q{o%T(&p5~XeH^cKocAv%%WR=$q$ZI_TjXRV)kq|Yk0jED*v*vq ziGKa*PW+GTrkacdDYbh4Ac=H{Bqw=J!|~{t?Bu-})QqxL%a zhfdS0H8bQKSA_lfx3z;I?%UfgT3T4yNEs*fF{@MVOx)~!E5JN4Oy@8S)!{IoBTp*q z+&y}q*7!*>vFJ1+_ijA!uwD;9-YHG3{tn&@$H?vz`TRp~cR#5P1PR{AE z_S|X7#lnJuAA|N^N=x^~6-*_3GofMr@>`bfIB|5U(u?yZ!?VsStE-dq^JWbRs*Wx$ zJDHf2#l=aYqN0*gQlYscR?VrkIX6to9`4gl73%NrXUr@(rW#(3<1A;N{&ey0Q5_Dv zcW+aYcG`(|Tmk~2H-49;-x}5Fa2hzU^`NMpT;@)E)vmo%f6svDFefLcR*H`AN5ig) zAeNENVuQA)j~|yjHE{nroL2lOC54M()7D=6m6exwyXU)iJkpQ$QZ^p4KX?`_($?6QxF zh(xR}7q5SAYujgKWmQmE7%phbw2euatuft~?v?PBBY&^wrwYra3H#aWLKA=`|_wDA3wjGvNGiqdFk2PV~>M_ z)e{S(ob;SXYiny8Hf^H#QRL?G>GNl*EnE72#GJQo&k1@iU}ZNuq@;AHYry;Hqt{jj#FD;!Q;Z8y zyL9PN<=3xrWJ6PZRr2g{Jv}|UqVH}!kQl1jS|HEf_)3aqV?s+y%Z@7C@Cbi@e>Hjb z(8$QtyxZfcq|BQG%J_)k<}__j@`enHdJR22z1+6E;KU6ljfuq+nKt?#?USMPVv~Zp8WRh8>ynQ^3%_sdp$EU zGRng=BMYP!`(N0S7J7qKuG`s>mwfuda^1#zmR{+hMa=p zjMLPSprD|aLJo-{{0Jh-hcTbdCI1BgXhzyyGaiixX2BcW(E~soZ1qhys6}!(P#PNX~Iqqdb+#M zIXa$xu$#MSXwzdXU0<5r@6yxXK3@7W>pbHuvYT7KcW$(;A4 z<~Ps~#cEG23W#H0s5WU~M~`nt|Bb+I+E<#Wcn5$=~H4Y}!sS9KR_3;*^c7 zoE%w~!TQqf+v6Q^`i0Jk~yJg?5Xx!8*8Ch&`4fCBIX>nB^nb&^llz#aV;%Ln*e>f`e)e)h%5DuFXG!VA) zc0|pWs2FD%^d36S%zWq1A9I~7Yq`eVT(6uKU{ii1ap&6Pln)vqGC_KaR4#Mjk{6${8O zQ9|q9|7ufs@t2$Dy$t`=4}Iurw*0dg@D5?Yf3^_MlV*Jvtmb>l@xNO$t)$+dsy5XX zOjUB4ir&r46sWGQ?n~hyxh>C0#n*4&zTGHf3Kv7@pHBEm7PUVkYJIWBgCV>hD@8kK zP+=HXpqID`E`9!wU%a5HP(O$--~G>*bClrv`?nXFR)yJxx^#cq_=rhFCza2KuE&Y> z+&f~e`UE+QwuYLNKia-;pRVC@if;DiEnDJH9Hsi(KA3I$UH0%ZN|&vzt>|L!PWP3` za&n6fk99ZVU!$wolh1@4IEq*2_IYpGR)!{}t?%T!k%nQ9gU|dxl*b#}&Z3sqR%0tG z1$68)4nrE@^>Oj>{MIczVcZ7QD0O>In$u-vWf6V-$BzrKjoP>s3Zdur20t*&Pe6r(D<|{X{Sak+{WJF;UrR~Wh2MN1QY;)?y(ZD`*^@x( z`~5q1R2OA#&f{Bivo3y1`lJzTRGqu0nm3cfLKe8>hG~y?@=ZG&j_!KsNN{ z{?5`jZFvq!T34e)-8ABrBQoZf=SDfz^RWHMqmC&nD<`5fv@SagH-)y>O6)rScflOF zC`>QU?j+K!P_5E9+E$tB;V>%59Jy(cr4Vg|`<;jfhkYQE2zB3Ad}{x!h~qgtJkkz^SCZtH#Rmt?Yh8YWMo7dY0FM?-9lDZSGVvdHjuP1n%&uwd-K?) zZA=Z7?gJ6G9VfcZy{#9qu6r#9Yh(2znoRty*QcWjVMGrh>ATHp zlH6Bko9(hqarcg}veuz^>13G4*vwB)$EwFGeQU3!8=h7xm0$N{QUjNqw%G_b51TURu=LvP8bX~rSJ+0az9SR z@+SF?#bHyLJoyJTlG~59@5QZFx?dgDy0SE!wp%_a#JJ)yv!j#KWZzSRC!wKIxG~Sf zJlx+tGPSX>DexETX-d&0oj!efSL@Tz(2cztf5j<1t?B3}x{$YW>)G??VIP_#HcvY4 z_*Wm%Alr( zo9{Sje8(j$I5_xHp|b!9#f83=mHErGQvdV6h+E^aa)eM!^ROHmPqc3KHK{jN9R+7d zoo@37h=z5}n-VQ#>euZ~GAB;ysM9yR0A6z?h8EYB$JLA7S0&o;p6>-t(|;P1cE`lT z6ik-w3t$xRU!ET)IuwbVoSa8cFdo=6PX1|7P)ulNwygnCH*gx|ucRKJ-x+m(^1XQJ zlBVogUpjIul*SU25x@KQKN|8}$iDXLaQ*A}cwmhKi~^P#iG06%dU*EG`ZDy=si>^6 zoqNbAz>&*ZlbW1-9EkSP&qlhQ+$ZbdVIJd2Z{M<`Yh6JTqy;k9ExZ(8PcJ(@G*l_r z>G~PCZjYF|Fp1Lp4hn6$`>OLP>z0yl;ru^yZ^o+*zc8rr^Yb&VPcbNt6ho~YX-W6S z#XW`+KPm5Qi+U5qt*24qE)^hZ0c1ZZ`c+1CTVmBGUG3+q$ zx>-qH-k(v(K7l;rDei)hU9VqQe`P4=#=4x`+_wM(B3a+Cbl(CBTMjPI4#!tVoQ)4r z<2ZCk{NesHQ}>5-UgG37CQJ|1h^emmuX&gSOv&H~x`ahmmUYo0O z9-X)?a&Y#Djo_Ta@#4VO+afi8{`@(FlMc+YA5^I^} z=<$(PP;hx=|Mlxv>I-g5Gph3J^al^7efspNA(T^_BV(**k(p@ed^?UO9*NtPR=g%O zI5_xH*y#zd<#p@-)rZBzfj5>Qn!oNuEiAUeU}u2#RK5?=I= ztFiMCvHpB_%gorX7a#{&Hf?3kcuoG)#nAw?dRRxInDAQEy)N(2W%EfWvTR5=mw#)N z+9r)-zM}Q#Pa`ukvkZF@vC3u@PcZxNP+r=jpdkk&)D<7)Zj8@GC5fpY1oSil17yQ^SzuI;!%Q9(t?a9x}NDZ{dnT3uaTC)2X@lP^tXsNm;M zpBAv4$WFV=9lxAs|FOP4IQQlNpZSkNATFofS59L;TsR>c8^(8h&qbP^I(6!#b<1P)dSfG_JDHi8b89`N4`}zFrbDej-T5BGB9q|? zz!rx_e^FPLXuwaNJfRMaKtBL8BaRlEc_V|W69e|6k%@^n2&!$tBqhnh!a}@b=8Meo z30Bs-R6AMe4jlMia)*NKwA<22Fu9V}*5}OU@0vFY^(raN%*=fG`7=Dzs#$cElA1t5 z8oWC;Jm45?Ht;C@`t?56IYUco{otRUAC95Hl22*X(r(^t*z(RO8Ji724=eREIz+jI zX@6icKIRd@_5b`}ety#86SgfW$F7fh_X$0cAqwruYwgd#EkA&>Nk~Y@Dk%I06}0}9 z7aDv_<^9#~jFydwrJZYYf`_>27Kf73p7EP)y>sUd$Z74L`D>ao=kLFDSH&3X<*P-!mjyD(XP z5X*N<)l+UWoCEgsB)*7TYCZy_A7!)DkY@sLJvb=nPE^#vv9U3H*^{uaGL+1WDM6do zFUgla5SL=SU|QL?`WBF7UBaagtiSSa#}gpqGCdHb{G0Q*ekk@*scKYC>ZN19@;8+{ zIjS%*HDwHDf?cq~6ENyMiiyPH<;$1P-0Y|Q`0?WgO3EE{be{TYW~hMydw3-jb{{;b zqNqsQ-QA7KRhyv7(wb$X8=X8m+-zcMDs}7DDWW}3F^K&vayyHXeNAzge~6)vMAtEG8x%R}n_jO!cxw zn$7nYf&(jy)6&C%LnEl+IeB@;Ha1G);^KGQ+}+(m6=9J9M%-GM3{Zc^T&aofdfp$<&9tWbqf2D$s z0A^RNT#4aB2l)>9Cv!eBGV)uL*ue^yD{7+r{QQSmSTYSqYCSo{PP;dteB2KRICAP# zn9KYaz0R{?r(N{)rFh$=cZOuB=hmG?g(YjK85UwP($YP{!@6BTat=ccWK&}_$_ffB zTwD()CML|T?pjb?G>BfAYqLE%cUe?WQ1FC)fh<-V31G!!ur99E-DyK8!9yg^X&&C( zG-yA?F_6TE`dstJG|RS=$-uw>J@6g4}lHQ!{4gMTe6fD zudkg2ru@>@mVY5ULdfCp>C?|3s@dJV`SshkE2~Sh;`)bzYTDXfgoNz!^76`YnLqL2 z>UR#!2o@F=r^UXfH?ChNM5%-B3o-J?12ne}#AjUVEZWlhaAC+^2n&r;{Mxk>qC6XYn$#nef<#n<3@(xymt?rz4Zfow>8@~(ARh4qeqX3!$HwgD|UAyq&+O^)3-+U z;AVV8amLoDO*fH&Fr<-CfCgz181+^)mXc_;{{l7ufMh(pydO(TeX$llxGvgRTU%!s zzP|eXd1=$_m4(S<-R!N<6FZ!Txu8*gC5{uEgv2pgv!(kr+_8KT{yFYm9^9(J2)gn(%Sksu5SZKam6aQ+01xn6ePfF z?K$Vbi@!qEYsgs0?1eg-dux;tul!>#bgiR6uF!e5Qs8K2!K!xcK>SH`@&xTPrm(Ou zY`@271`i)@A?@9}_sEeWU0q!hEhH{%mS@lQ5FoerjEh=nW+BJSKH;KqED;D8%|#`- z9_ylDL4Bb4$rC~%a%~TP8BDpH|1aI*$Yys+jaziIKcdf3jIJqzm~fdB@*=KSlGcFW z*|Ylq7+Nzd&V$iXLB~S3fR3dp?-p>w{eh4eN_bzridf36f%0eaLv3b*d8b&Zypkvf zDIjV+cNO)2B1^YI%X4eJaIV#AKk#gOUqkYxV6oLf73-FFF|84uEiD%btrwTnyfKm9 zws`f{{n!%vxYyImuLr82Z)SHmC+S2UG+`faFdP*8J>2kiCwA*`%>$9mYcmWmZ{tx6VSE0n)xmR_|RhP$Nv7suOe0#=QGrP!MCHqdVd0jn- zbkA2`2V&Xe`e<$Ln^opH4Ci>PyWcrvG}Zex^m2+_Rdsc0My-K~vsR6Y zRIod=dYBWZG{YNXq-F)&R~&J%3Goc~g`Sa3uh5x3Lb)99g2vh)&;G5dHm&H*{(vmT z8FY(1sI;|}?yUh1?t~H|9k7S21i)+oeJ$XU5{j0xhDO8Afxqt?Z#y;TAmXv+YHedf zWBnmJJ07*Ubs78LUg&^smNk1wG01!J<@_)JR4;FD-08KQjpx}*^T&&-AP+{d75^=c z4%%GaU2WO6Sde1_o(MOAgOD z*G{pu$w1#J?#p>0KpnwhVRws*#en)vQ_q{5vze3yFtf4Ay39N!4)DwL8=Z|G!TjRU z5(*|h(KIA!2W~weG?C`9O4D^;M#jHt_ntj|%JG~NLoMknM74fAFS86$-Jfe6z1COS zBU0cO)Rz&CU3?&qK+rdC-!|*{avxX=d*&SU(aqG8JE9mW!?3$<79j z%IL<`;(XukRFG<*8`d_R2PCnF;RaG>D1HF7cR#ASK3QK;o2DBJzs+eAy6n!<2O=Br}Ru>g!p zAzS<`_8=|^5EeN~#P#parUQK zl%{Ok!_aJCrXg;R#Rs?+;23Yg3zM*!lT<_(CE4RN0H_Ml9G}<*So|~ga&`*XP>H@`tzqE zc9F@{($XKz2;WhPMlB{LhDPmK5cCqxU(uKCWv*w=ocR_hvd_iE1@8peJPhDRdMV<9 zy^+^7IQW$)CeUwh+_+ITUSTGQ6}=8?BeVJQ{FCR;pTBooz6I|2(A%40>(;GMAm!WE zzYBK$NYNE6f|PP-{Dv&ne};Lj7c_$B+gYS}09ho;1N{6B2@Ai}Ow#He7$`@*h32#W z^mTECos5i?*yy@w1o;xSRuq(SVPW9~FdkKTXug$jRcaur?G@boV~FuTvH;ig zVq62!1{tiHl9_>qJv~XVfSjVHO$P+5Xd%p!Xc_76qcIE@8CI9R8-7dTq%e1Gjx`5p??;-WY013 zUk%8rsjT$3En1|6)`8kk4L6LYH#0kXlXzM)g_C*@RF6L`>9JvD<>m1|cw=K@$;|6s zQwc?E-MMoox=|*#3T(U+Cr*^vmktmG-oHO7G z6;o5iD-hUeyLx)mqQBwtGUo49k%B>f-_H-_p8|vdy7e8XPA~_rK+FakBTQ>9H`RGc zF}O@*o{*iaR*Q{3Qv%(Q2^TlN{@ZtNBz~VZP*hS{1dqRjRzPT@C@ExJ*xfV`)Q|HB z8DG5$eEC19F(6^)l*IY-*c!ECfmJp039vRHQ;;&mjvu@ne!7zoBCXO2%Q({tBraTd zoJCSD0uK;fTQDhmbbtoTk%ZC$b5HaTWS5DF>yWyDuvIfxS&BI>7C7?aCVeR@>w$P4 zea@SDBn`+uMi`f@b+wR$w#5;`x~}j94Ux-pZFRmA?1pWZxtI!}yqZP1l@VHsth{`k z7k`C|*1_KIKEO1mSC{7pu!v!f?^-M+3a)2CXbDV=Z6%PTs5jhOG}RIW5~ehS9tFAo z9`Gte+RLu4uA4V+F8TibA>=2^K?O@Q_w~{CTyi(7RSW(H`OI2M_ zQBqg;L`7^hq|<%*AwHkqs_8gU5NvKF-}{w&bCb5Vc5+Gz(g|$u(vHWnD7`qcpd;RdE24M#a^@l7^=+n;SHNZeJFB~cl5RXb zGt~G1tZ*xna0SlfB91=h*lhM=0ra}fFj zbPJKjQ(8VCICV+d+#qVwXj+-0P&#@+tqazchL46B89$j%j|d6zK^=$b`5PtgH?kAN z-5wZ_xp?uSZ{|5dzJHaMbn4s$@+voO-D>Js@80HNSQ*0J^7AKR3)50kQoH~$gtH9M z1He&GM+BZMbqQJ#%_yg(&!kaDM+e}Z)i^f@Ia(zzKR*i}pBhbrf1co_UiR;QvmuwV zuN^?@reL;7m(W`wcG2f>FVyk@2+=fcv=LnN~4~uFj}` z`~DrhM(}3;H;9@aS|2HfNx4sKbP8PlndiWXO8q-nMf78J^;VQ`G#Buv=UJ8~SH@pn zx_FVtY3d5p3Lms4K;#(c6$J=PkbsmTwu!C4!lEO-AnV#MqIsbU&@!I%14U=xm^NCh zzmt@=vb{~)z)iEQ33rBkz27B61f^x)zI|ZKDj@wi;A&WUTw?1h{6y;mrbJ&rj3>gf zcDICZ5|i6|pMuIYi22l-VVW6#0ac`kixwHgy&@v~0Wn=hH*^klg@c_PNfT7Yq2l$` zw5%a(Y3aMp;J&+}Vc$`wG_71Ol5txe%_h2egqVju@rP*j4&xn{VMm6BhZEZW8}x+K z6rueG4qT2_I;IkN{CWXwfBD6Qg@l9zHsVFDZf=b*U*2L_(?=Jr&gq7}e3=XhB*k-w zcH{|#^-w9fzR+1mdWT=Tj#WtQyV1xkg*oK1C_%E`UYq- zU^CiMp+x5iQK7^so(N?bd;6163>_UEe-yghR#R6;a>(oCNcRZYv!OOxcNB#8RXsH^G5L(9ai`#IaL?CgFJ4&DTqHYb{v-NJkaLBu=jb+% zh4bka$GNyHAVp$*2*_Vf;sm(Ig1%E=^$Y6T?c4J^ia(}lr$x?y8b>C1DZC6^~94EH-3;Wm$~G+uIQJ+Z2l^eN2zTWoV-VXAfn)^pcOgAOfxm8H`Y zkUgkz+3s4U%#upTQ@!)Ajx=61O720tkKUOzjcCmTbec@CJg|Y=plCnT4MxFh0l5A| z6GLAh5t@pj*acn;`3viu3ZUOg)Dl8ig-%S` zFXsLdodKDND!=V48D`Vu|IP3@3{Vao>Bk$TeMM_aRs{tG@IolW))rXcXnX`kg&XrY zGE!Mfi$VR3VmDA4@quU{{5Sg*M@B~{=jQs+Ys5QZpFrXB&CfqeT(WVG^|KIHT$TKmd?|`~VIKj)D5^H2>>1?;cv$ zwZ(zgZ{AD+a(n>AL~|;Krf1%k#l@wY1-;7$t#P7kpDpS7(u_sX(hw&;=)9rfA?T`C z2C5@^`}=n=F;yd^_KeSzTEMF5HHZ|j8*-GTDDW+aLE!B7pRx0S&J9hX9KHyVa|6PS z!E07VZ9OOq(aS*hJ)zwYj#&u1I-Dx|xY_uBZoTj}`FYw%jtV67U_a39->-=82k*z% z;48{-$^XrQ04pTXF*5o;ctC?}13gHjEAkLf`EbgU6BCC39I?v@$p={feqdnv$B%bF zerr*c2(T>yBvw&T(FIg>Tqk35p}q>JpI<=0@%O2~J>>w&BO})6bQ^j%enix2fbjae z&`HMC{|NkD;EX7NPiAiw<6(a#e`~b_JaW0$_g)#i&#uiEnypjZGF!;$6 z@)7{(>$h(=*A*g|)Hk~0pF^QLnvivF0>pLi*;~nT9k42a>nWT96*(TE55p3NsS*?x zCT(X&SPZ2Aga8{m_wJR0ii(@^d$!qt`*Aj^yD2oO@Jm5$Dapw>u8Z&IM46dm6#M@A zh1i{J`Ih@O+#YJUkJ1BE8Pw`1KYuXb7e!Zp|K0odsouVQ3z24b!AY~8X0}WW^6&e14=#C7?~5xmq5|V*FZpuFHZ*nXN1CE zAyo5IwjBYmf*@v?L4LxeoNm&!<;6`RgmfSg`Q-Y~54z24hxu?K zW3~G?74w%5uUkcroi;!_fSz(%NJtI+nSA*l`FO0&jnFZ2Z~Uf255%oEZ-d$MzXfYy z`n=O(t1~;{C1W`mUb|Ke{!HuzkJVv=Dm^Vt59N0W7wtqP9S+q{og!*oQo#T#C+7pe z3W^Ej5T?K*NlqTkgft8&aAUe($$56D6e2%$Z{dyKcTXj@!FEJ6br3EhiMwDzBFG>I z5uE2@E8W{5SL|w8o0yzxR&iqNZDr^?+WeSJF7p6YwKh;X3;<0w5+#p-fSWbxugVPw zt#t@LLBIr>SgZLpC_e#=r1KqaRYc;TDvZlysNt=3Th>Etl|8e2h`OKPJ~!T}lA@DI z5GWva&Z(xDv1B7@c~bQLtN)1Bi8UH(&kC%Ql9I?pDCjYE^NA8FYR5CDoJ4Ur_~ zec(Z{)V_nf#v7ogQBF}FA($Ic6lP|w0Mhr3km2htHi~XeO~wBHg3Je~s}Shw%1pfq z;dk81$lCTHy*Q(3?NC7ymug>ok zcH}|Orak9|Hg}#6Yfpc_1smXPkW+kldd-trC+cK@n z(Nf8BZjUp8PZ|?`-x}7UiJ4hBl-Y;M@t>QT7~uHq*s%ktpKgepz+=(kNEnL>^pj_X7C?#RQL-C6y2*LCxi z*jKOoP@KPf*$|-||BJEoss zmzIcDdVl9JSj|M!A}ACrXCBkaUHvstH4nIpDv;hJp*^wvk1t1tf*wXKij%70vL_kE zW-6*$rh79-Xd2-6cz}X%aD8;OYn((Fes zY4spXiqH499XotjqU{tMB8C%sFfd|q+%LsEm_P#T8pq{Ox2|K*0gl9KLtw->x+Co# z9#7zzkTbTL2_Ba;8rQvF4JGVII>IdynW6j6mgQ*)9|I5WK4XcHF zhXH~M=J}bK4l&zD;)&cx22wC60r=hRMpjaR$QHfrO`HsRv0!5VrGq08p=vJvpu7w}(H zwx#)TM81VdxPPul`69K8Q0P}^n;F7Ld6ZUF(ZF~?q_3j7`h> zTCfp_N{Wb4dy(5dPd~rSfVO_HVo?73k+1&?YyTGtCAoqe<3t`3>RaEh0;dl@Za}gu zLkZWh?wp0)3Z0eY6!^&*dHoERJh6o?3Y*fY^2YTW<(#Q&+c-~LhOdi_i0CmBqE4*J zFWK%C@K6)!=e|={zwH@i%9JsnVK~mlR|Dbm3kvyz_GUy!peS;@uhjIyg}zhtK0DhC zKosbc;l(({MtppHcD?9F0tlgx?K^jxeB+>DmJGE=dUs`IB>^JHolz`Y&Ws&%5XzO2 zg#6Q#vJWN$3nDFqC(0HFtEvZf+DJ#?3qmo4t_(qtC|Zd6Y(<4XLFf;N=|DM%zaWBx zAvzNNtr#gB4oAWw>NCnbR>(Wx3WArQwvz4PyRsQ5=-A1VyHGJjF$EH$)}DVm5JHyS zRIeOr)p-=Og|^N$$`b6hX989X$gLoJ_R_$8(HDyEtB_a7ksdjEG#%)p8XITRXSv55OB>gXO5-pC(T~bui0m;g65Wm+ zYFCPBRId`Q(@OYcL1zBzxv)&J$m})#QzlW{Oa`>&|2j+9AP)FLxJrHF<7tH|a&qi^ zHALp>jY^b$ZxKjJQb|dPU31crK8t+bB_%i=5WW-ON)hS<@>nq>2Q(bxX+l^8c%py7 z%EhHb#vvq>*FNjo5S&q%;S>-tc8T?0#4_sGU@=y1B0LwdTONd0(||VB00&MJ>@C9$ zHC5d+573hkt1W-!WeT}1WmJCuu89nzk*)8Hyva43o%5hNMUiK8#=6Xn zsA7ZyLlRJ5L(=D!nTj$TdVwzOTQZgRssf13eN@e5@7^W;sn?P2qw! zMhs1G>E&El9S~br#lP`V(X6%718F%+V#zu70N|Do0CifSBb%C;X(t58d|f}Mx`P-< z3wZ&Ajw|{aNCybe(8eaEuo&s!p!xz5=7ITiBfa^$^zD$*OorNa#5X4RV6V3EBVg#Owm-XE(AjI*SCg`Ik@IlzMr2 zW*?gmoyr}UtM|4Z;K%?o^f1HJ+QuwMl#`X5Y3Abx_V4#BkShK^JMztc)c^3aaQQG+ zRQO{O{#=a$cj4>8bwK+;n91UImeW&GQZg+Hp=o`Dk%el8LPZ^7#BMcHb#l^j0ETAN{9@e-AA&xdVMmbbW;oswSqVKmYm_0e=Vj;WN0Z zT5CXD#8xIG;)vTF%t%GNf6hTn@}Le8!(Bfr%TeFDvOC>5-=!eep$E6uC2GCY2ui1{ zvhvmOjzU5UftJB@t^G81nheq@#N-nalSE2uVZjk{_{9V!fVo~^pw?wLwKsacP>~ds zXwqc%{kPOt>uUBQdMQ&|KcVZlh84G5l92GyYKB2UNxNsF#cpllp4bn}*b%)FnMY#O z@A&ZmNba~aiE*5XYe$LY`t(f%)aQ*}9dKal&>+-8*(LwZ31}n`=AGe3a)etge!f47 z7M#!Ehidi+1ZoNv(@r|N5~vC^y$}CymoS>|xf(Mucm(VVm17gc%5D_$)>RX!+5ZtQ z1g3uSuXy3)>}($ZIlQh|OG1>tiwku_8PdNb23=<3xB8r2(-SV(3#8gIDAh z*wSB-{I0-Sxl_PRvph5CjZ_n47bAFn1q(e7h}$i`{Qd@-0~T)tXgu7VDs%>##^2af zhG-+u_3h?HF5&WBFsC28*T;RLZ(soPLG=uE92Pcy%0%HM(+=H|gDnQD8H=};~8~w(;u5|8hg^J+qCA`u~gF% z;3gUnv91aqzZ3~NLh+!d_k~^rerbX@mR^D5c0hI5@QYOjYvj=>kHEZjkn}l&aUUeU z2}_qqG7||KKvVs+O;cmzcChQF&V-t3MrQ4c?ZhP`tVhUn%~?b=;3Xz8a6v_~#t~d7 z2Z_LBOb_rE242G9O2Mrp$UUYxMNl(=W_KJopak|+@%8IRtRVyi5q8l`brzFrQ+QF{ zG8k!Ew@LHq%NJAZD(mcVInJ{jaQROn7hl0%u!t@yjcFdh;*E8RLC-?1NRXTz3-}ej*$c3K#ZUt*eFVFryGTDRz>5Q#)$U{oy14niJ zP&R7a3B8;W0I~41w@(nr7=WmBF5*8$rFwY6u%1Eq+KWA+P+=!w`g|sIcjWj1ef496Da=w^UrQT4oXnIyisAp_U-}ul~wBI4po|29Z{j-t2zEZj5 zh86qv+BPNsRHyRfTyhk!Yyj=>MIn32L1K7y5`?qw6!ICzj~}N#UZ$>vDU6lXagPDK z08}Fq-<59HSE;773Hy5&ZY2lrug{&E5%NJ@vTfKHCa?Qn7oh4tm{^6NCg*=-0sftp zX?NEr`%h;q*+51h9F*is{6yd#VS_y)&i3hU&54?vhsLW|AQE9<;|qTNE+eBC?i2ge znSjOKZGTlW;rYrb;W$3lv@9a9jPa=y^!lWbC4+pZA4yoTjo5CSADrn^Ur(?6Swq=K zL~r4Q9b;-_6w_ZFq5EbkL=BKj32i62BnwS|!LfQ!Y<*Fs4|9FAl-|x@2AY^b#gvK` zX78vkP*Bo3TEjr`zkgrVlklgY?*x-;;NokbiRU310Pge{bA5^6D;ywgNZLqB`Y`es zdJ?lT#0x7m0>LK|&{8=t8HTzOk8CDD*TzkolF(oh@%1%BKq%blww2DJOr`iXKL zda7Wfu*R^5HQ~@?af^st#_(zafMI#R%D>rZmWBRSE}DM?cV+?%=mp~^E#zIOlHP-MgZRn5?OV#apymj(kh{F*&c)6?by#4O=kG@7Qzb zG!B4_h&K^op}n+}nbtq~=$V*Oi5|Ax#8(yxLcSMv+Y0i3()&mY5IxT*JKkl*r zW=fyCF$;%s&X2_<x~b{-VI=|Q_(0BmLO?x+39m9+UQCW$3H`B)5eresHYv;SZFGJ7OW+*--%Rp6iJ3Rx# zsoMgKzKX1|u=@K`??$I|oKNn)PNzqO;Z=BqJBvsZhXe!!rlzJW#}Wnd>IU?pQb2Zk z|NOZ)aOk4yQz*CUIy#J4A&4O14TESLM{!7p4=*7dQ&Cdl>6cJxALreLTS_htXVo4$ z61g}eS4l}cC_r(?eIIu`%z%0Gqkw?qtd+Xiihj zjA)~U%{-lzvoLGU4%~}BKhEVkNgm#g*50TnV5y@qMIq;_E47^OFwEMksjlvwmq+*q zUB7>;4+sJB?ic^sGYgT8&=NB;Gns>AuOm}SJ>78fvPC1;XBLJBM&{-hlctd4;f1!? z?SM2mNu2E_RP?^Fw8Vxv=Z4-TJaMCWcqxNE(?$^OQ2*-Y#?G4#xhnL7d#q^WRpu&m zN3)vVF!%3eekGK)rTrpd|HDWjOK|Q8j&fh3B64L2KDL`XsIEM$sH(EcFnKrU>)pkH zp&KgxWo%H*JY_SNf#Kl?Fus{(VPD)+Wc>`_VJX0Gd0q@!>N?+=LX9H6OiD$jC@PnOR6LJjCfzk&vL2RXXe zYV43W{7~SiEcp5Ocx*d_iO(a3k381hbEhCP^1|lBM-ZSDd+$>bSYJs?%bumBrHPrD zq9k*`}N=o7cA4F0Nr(}WWDl}%v zDYd2Lt!}yD=H~|@BMTi-Qqul+*%mYz=Z8~`4JdK!92|*Fi$s<9P$L?P^i>dmitoL9 z&8KZO2Rbf{zIg|Y+%E72uoQ-^VttxX2sU^^KdS7@&dPcN&$(eCJs*?#ZZA--Dlj>J zYph)k>p1g-cfvIf8q4SLG4+|I?Uc!>tv!Vp9z9R0z~BfnaK2PL7%P!QPUHy5e&&zr zldo4WB`X8m6N~eyg)t&~oIxE?*<2@a+-xcmrrdo1-zA6&yKmnMyYdqvHL~vRqPSK; zpygLlC zj(|hRvuCm(P|WEU70=!pi3S=2J7-F{^g-G&`O@@{-Zz+xKL!vN_ z_YMe224oZ?4`buQd-v>leDOGI`o-fbsx6T5kFv7jgqT@aVmayo;i=B?sLEX+3kjeR zb)HG6o1|}E26B-swpH{;# zkS-~S2`AR*DNx9vXaT7QtWspy$PaycC58uo=pej>@l#v*@txaopD=waizNY@QqkGj`P0xw|C&(* zfjAE2j|{xWtt@n$^wKYKm4i%km=yB#>9GwT5e++Z_!XY|Lfxsb>)dtC>5zrx<(;HF zL`SjX2ttr_nVvwhgx3ux@9=%e!>$K04dp%Y`IhM{mk4XlOu;eJpDisvApPF=BUmDI zN|uqf{M+2v8B`xfAR=)bXMsk5Yax5$sXD?hmvnTVU^8v{m|TnQ{m{#c90?RAuwud6 zn$H#8yi=Fnq$%Q7NJ&dm^K-(+Qp0H0c6RRF>Y91)<+*d!>rEXkb+)~F5`9KkxIq8I zxl=Q<30Ce>bgr1n@0Rg|h`MuoExwqzF|@R_=749P7EkD8_`x@mhW~pQJk@z^ zV5|&40A$v=w{OSVyh|b$DNKq-1iPuN4Z;G)g8G4cn4cexKbQ#ZbrwfqjsF39mp2gZ zwL5dav`2ouqG`5$-{CYxRu+;(bTNijp*kN!OQNQwJ@V>FhjHoCfcG}pn5tX?Rj=Y2 z4~>daF>sySNGw-hU*8`O^lmw&0itla-BER2RCE1l_3dVw64O>Mt4D2~jheazw|AX; z*TerEUJAb4XBDLB*zMc5mtf3>bR6SYRCPtZqt7cD!OM(KUzfo*<3ozA=~e)DiIXIK zn!4|QC}-w%xIbweM=n8^yxG3$8syT$xq8ar;Je)oG0|d?sj?B9OmQKm1t$+9Nrg!0 zp-I(30ZmM{z3gR({fyeQYYthrNYds3MwDiwy|7CeScf%S%exLe6L`bG%bJsW%rL6aaO-*dUzER8xk;FAM>5bEKTJ24VJi@2q%!~|7 zjlP-DcN-!jW+Oa-z#eCDLF)U2(Fq>Q1~$SPA)ZM>h~&iR2Uc(yB$4jEzKtZBmo>UY&W7ATcyFgy&iiF&GlbV`Xv^A~?J^ zdL&`Sl9A|k?b?8FJ*ls44EF<1x1leK$*!mdG7f)AGd zjgb~!=pKe&pB#lF;K%ckiiAgSoj=Y%6P(3cc2PI_)ho5WHNg%?3YAFV?PV`^Y)1?k z9ly)Y!ok78$ijmC+wLdf;rF4^ey*rUs3TxoI;3C>MsIg=aw6gfb!!l+x;w$-NyIZQ zx(gHg+2v$qOF)={A|oF`>ga~gbsCQ?2^~0#{}MCQ;D^Lq8y-(pZX^MW*#UQW{`i6H|Q(1=H1MXA?J>G+Jyw$K!c5$}>j5Hb5Yb zcvKEx3o&y{yJbr{o^o;e%o!u%yfGLEfEu#K<}vYc6H&u)WcO}&y6q;ERwVa~EG?;{ zkF@ZgIwcLMACIN56<1Q)0&)K%hzc*#rI4Ly2-gU=-G?vRrtK~W>MM9xaK_fiNT(t5 z5+?%9l+7*1T#lGEMSF^ljwZo)`-F%PkMoTAOHnsQ^b6v)U@VgTHTSPu)EK8ZMKXk> zb3s$H6j_0;?ryS8n>GQ@Z3BqFJb%vPHF!Q35%qGO`9lVZjj38AsPDv2h&&Wx2I+&0 zp1ftx!;SkW5lgM;vs=L|0_lPgoi(QN0Z)lg^5LM(2%warMOUSaMLR|W1u-kW6oB95 zCwUm3Ktb{ek1{bf22Pj5QZ&NO-*fiX@sk1qzVCO5^)Lz9Z%#~1BqoG$u`od3Pl!Uu znv*W@?R}b_&U=M#FZy>nlDtNl59&ZGsUhdU=_JPP_nflc150WP8tV*TLhDkPXgN|$ z6@612Z3uyN`XXcxffBwnlGDYE8#9npcLbLwBAxJzx}g6L+)uw4Ysq_#$0XUo-_MVD zAdOG_4#1#^nL%}<;={5V<=6a_v4PC%U(>!)-@SWR-gN6;KFNh_ zy%Xh7?1_{!@qh*CDr14&K+nWiKwqVMP>N{CJ*-H?KYUQWSU5RpkYtuvsg~Nk z^2ECTv4&0oa&aUmj-D|}|l}V$M3rkHZ=M4h$`qQk9kHa`36c;v(!GTq= z;R!g9{D5uHT6dJKR`%IJNr@!}0Pug`a1L(09C68YG2Sp^y=FiPUlX`*5lv|ZX(vy~ z8Uc@AxpqxI=~9f9%h;CC?C5CmXA3DawB5uwEgoC|c>2jDuI*96m2a&m@u6jr@V<7E z2*&O+2cI+^5~Q6;yncb>IlSW}rWWl!*fnWgt}cAz#3*!Gw+sNvfBe8JL~Y^P=|8;M z3PmRlu|ri{@z6o}8uqD$Nt4RzYSzQAaG5JBD(L3u>FHGwFQDJGOG8J?bUFl=j+%ys zQ}9eP>;ujNwz@kt8?|EqcSD1!`gS1z2j>6jwXpzm@K-igR_Ti1=g;Nsatq296@I(C z)V$~7wbvx`O=6<|Kur_{o0AXmC@ROL8FmzVqA(K{dEeA71_rG5-EiZ4A3fTNJa|xO z=uu(2IJ^y6NOMa|VEJSfgp1?CheK+N&)>e$Vhd}&;S`DYD=HEN^d*t- z1FT&7Ifp+#$k0hr>`u$$5+)=i5r#+!680PgPw^Nt&b9Q+8X zsrGgkq77im-jB5=%N5U`ry%TY4DLiHB|Sj4*BEl>Gdx~~1l5)a`<$3*A@-k#hsU3x zAqfM6gBZvuK~A?S)Csx|>8MF8A`{%!NE$utU~&*ZM<5*y4rL=AwlP>tZCWghS{zqC z2JlWi*I@;rCgP!khG zm|eNDS!9DzD{G`TCU#gBT7cy!|RuGIi-uRN;GW1Q;}b{QD_ABO|r8b~7bsT1Hs{x5>kY z-iH5tzZoVtNuK{dHI=?PY)0en&jn;vRJd=iR8DpNr;Nh_8;?Xf4V4~Q!2gf1KY{CU zU-!82J3=yMOy*1#QpgY~Dnn$fWGcu%MJO3cWGa+K)T#&>LWT?})sm?sWXwGC zysxai&p!XN|Ic$?>vi_tYgzUC-S>C6uFrJw^h@BiFn;|nG^MIiEX5L1QNXmfuTQ?w zMn$Z+5ppCBMfym&5V$l~QTGkh3(dTJyAf^L;j|1AJ_5+`88m5~rrYxnQh77e0eRb^26Wc?6J3kenF z|J<H5V7^B1^1eV8}wtMtV`#m$hov90+*? z;B^ZzUtlW}E!L!nZT(u^j@#sel+x<`@b(RqvwSr4p0L`Kd9Aj%tH zBd4ICx`MJ#(OGUWu`Q`PO3tBCtvP%aal!&9ErS9J+B9X#N{Rw=b92Ra`}QXAw^fO} z8`{1B%E#o)?*9e4NWpf0QV>y<{)RE@=Gho zbW=i9z15A4jTNh`YEK_O#ywwy&MNd%l`z{~KX`WFmKSj6wh7DjzZ8<~2|fRoE4gGb zSFm#S+O>qqMPw(yCASuhCpT~s>$5-TQ0_N9&ydC$7cKnIQ`BzN|M=ji+4kc~Xh4m% zA0_T>K5gIj!nEsC-aL7r>2%!%&0CXm775z&xt9wzd$EHK{giH*M+a{iEn{a8Qsx z6eDK?3BWzccO0cQxF4dK%CdQ(tXS&9i@*{piu5Q4hi!{Ee0b{NYZxFLBxa0gL<5*> z#dk!<_>|KdTFv^8zToUY0~hy+i|enTnpF4F4S(d*6Tg>wuonu1!KS@r*%TcEwrFyCG$f085lRroYp z(u8b)Pdks1PA7iY?o_k7bFM7G%+pTXt95Axk`*n zI#tyrq#zoN8%KRGO@P~=^SZU!w##h(Lz7q?aXBj;Tn?t6IFSj{g(vzMebs?hXHwRl z*3SC^Tn7U{B-9AJVSA0(F@JM>+j$mJua-l;3aSGIMME`oBX&9*E2MFmnT;^6o`y?Qkf z?K*{-z2gK_ZUI3-mf+a_-CaC>gg@z|O?>bHB-+wjBAnsCTZ^!Bpnh1pZrw&{9wFJt z5BgvH&{x}hgq#o9xX~OUJu)iF_P{sZuiP`$t5>(()OLQCSLFj{F3#(?x|r)As*QaK zLdGm1U#SnJ{sH6_XR0Lcad&BxP)@%Hz|vr9)5eY4cIi@^ZlKA^@`=eaYD#Mk{}}la z5e%uF)zN-udVykQ(f(^RZ7SzH;cl%6PpqZ1(a}-kM`w}d6i7&HF@Bd!`S0k1Ad9L3 zC9T@9!7A~tQrzZvM(K-l6RXx;-MrPYf#2;uee3M$_w(n^&LfUQMyjyI7CpaR^X5KN zkr;0d3tNX#Wa01!HntrfE=@2h{vKj`$kw!OqG+h`+}4}~t%r2mfD|mr#AEeyj$Xo2 zSVJi*FzfsiuH3WuS#*zYe|+@-<(SSzW?*1o2EkSF z=whv?i#c@g{)ND|U$|0B9zXU&mm%%ERjngEq~ypST)wwxLzX(A&Vi#x>+^wYD8i@# z=vkRQ=}b#)*1mxwT~=uI{6NEk@YMA+J`^TSI`pB4TOX^sA7CS#lKPgRst_&QB%8Ctz!e;yMAwW7%d4U6O$z09ae2yWuB+W3>&^DM4pj1dt;mq6?Hh#d8fbs( zdv?a0z@)SU>kq1?E56i6A(}aB{`^f?*syg)(7V=OZ}IHm8B;~=jPLfTRTE#n5IhEV zBI1-xo~wb+uOI4{tP<>#s&FS!lUick5s5rk%E?S)n!>0;7XOKgH|%GdZ#rYG-zFT9 zJFlwVo5o8#Jl2GVYbl^O*3Q=_z5Y2fRQG$!?MZ17*0>69<>&iDoga;!h-UThv@>;S zaOS>$PT9}7#yNdK4(L5|26bt2KGWrDu1(A(14Qu`29mc0=DThw-H0h=EAKpsN zORb>&|`m$oW!!);d#T|6`V$Bz|6`paQqZ4RA_QiQD6;S9GamqM4IQT+&<$qr>DSku2!Y7GK{?`SYIHY`P37AzSlIi`u*XLhV z#1#TYR-Hmb@HqMo#cFL4!KV$1ii(6vgc49f68d)sutTU~Mhhk-7{P0X#8<*`imgHM z1#WaWx4N1jvCyMHaj_p-j%~|6p*Z!k(evN4XOF@9=aP7!z@40@g444e-x5s#-hfP) zQQR|T@R?v<5*|cLib|>x|KT4T9K87{EnpT23*tMGvN?3S2w26nLaj@)Y|hC7RQC2p zzc&v2bj7OUftCPdXjFqaq91XPe8DrSfrStPw3y4m$hcmXR*U>WUAOi2O1H3JFJNmo zxtg6FZ+n`z+fdu&$L0udq zn(^sLJ2)D}dadfqp)r_$A4P|n;(909pQyG$$}_I3$0QFZb0{$u(Gj0|lTY0yK7wlJiFoVjF%~4^6v>MNmC2BGi!1b`gXO*7&vxhE@v! z$N7jF3J>D|l7=c~fLt8_qDp>TwHi6Hqmn{hcY**=Ypk=J90388sOGA^v_(UyY(zY= zHM=YYb=|^6iw>el?QUSuhK@iaVCSdV&zJdwb1l z)v9fotbd5_ot%==o*u5P+UaF)wKX&{AbZp%B6J%?6xyI>FxN*a!WZCVr$LW7etbtj zfK1*{OuWB^2z?8Y%s)_5{MW5(r~#L$u_Zly`5vEu*!5|P_9bWCifg@YeiuDGy&b(= zwWwBa-?Md;lf)^gnD+#DusS-rqY?oESMll7VEiC(No|^J^iScJ%Y1^-$=9N_gZVQ6 z$0`c)USInzO=gYj1=dPsr9@E3D!!E4ks~hl??E{5s-ZUBdv-H2YD^t7E^fAUUTA*0 z$85>MkSb=^g464HQBgmE`IR=iXM;u(4;hovCFaq+t8sH1HvtYnZ`}a;fI%6nlaky+ zKh8+#3oE!vI!kK7^7Fy+>AOw>@R0tPk~-=$(tusDgA+QSkjMnt@ry8m)8WBgV#diT zE(C-KYGzj~>{yR-%qVKvBXn(gjT(elzv2zJtBOv|h{lT+Em9zX?Gk1+XwjleV2#7B zCz4Npf87sZgSNhYU6#Rxes4}4NSS7788x{TjaC2U?<|%jYPOqVw>bW&uqo4%G|~N< zGeYE_Pb~mOl3iEIC(Me2xVZgWoubJ{sZ*beWc0Xk<}B;K3X(czKROzXrmjwseIR|S zcJJOzQIkq$f#_=#Ut~V8iYtHrT&mPxT^w!&HADBk7U9dwd+7~nIOQTe`YHDIXj8EV7aVAVh)qq-oOlreJ&ylX*cO2IgY zD;Xe4gBF*T+yNKc^(iJQ`3@6W6r|A2A4St4&S+5=aVh-zc*G}?-O1Wp%g-iUX*H|T z2{R|FC2>sphP{qFl6nKaDEtdBRTk;CR>1XZdC8C7-!zpah&)COfe~l>pz-6Ig7}k` zV2=4QsvO_9l#UvboLz92C&rDaiL@OoSik?LDRwjC zkAgBwO!*faiPHLmP?w_lJ`3EhVy5=`)vH(1gpez#m8$Dh$J%11Pk5|e(omb%VY{ox zTC@wjJGJMc@3!Nox&~h=JhoEnn`h5OzX}otJiYPC?xe>N=e=u37H)TM9wI#sSoazX z%5Xqqmi?v&QL9z!eDcifh^VM)90*YF<{h_{AV|GXqxFh52k$aMfV-FuV;!yI0d}4+ zVK~AW74S0%m87XB7)FVhac2iFbRV>VF93_QvdDcO z!E_F`x8G5}_U-W=Q+}r{dx+0Opl4}ALmu3`c8wgPD$wS7b*gvv;IfjR%4u31h#25u z-@hikgtU#lU;3#uj zXHWllzO>B*FSp;nyuoz`>nhc)o_yxphE{x|8IdO}#0?QL^#MwCbaZ@Czd+uur%-6q zp+hzCWchA=8_8ZX2V<$=rZ0sr6z?}Dt450!ff8vY{R=-W$*p7%xIe&$(0$TJ((R!Q z*n~{u$gsO>^7lqZ&q`M`b((#iJ8PER3*~rEXai}^aurR5)(;BXPG6}W@nNcEIiV|& zhYocbF~WBHi4!LbBAZCoO~&AXv-$t=b$lC_fpz8^E7eCIaM+!cl_|v81GKrSTZY<{ zq=9CtzhCjK{E+Co+#b@9C!uQ2N?5oNlqm7G9cQbo-8k(%l#qaah5J^#8@A`_yl%mUTrg_Ll%N^1Kom>x|D!vy*(n}4 zs&i`_^Q?(!u!oO8eaarxW4j=E^DpGgtUfw*><t=f17)o= z(k?+rC~|;U8+9HIHPs>AQHi$}Gl_!ty4fl!(`g$ej)GTc^Fr6A>{HtGcA!ZT%HT_L z;t2W&o|i?&ZpikOKFccFfQ?B0_zy5)YoFDDM)(MO(21(M9M_XO1~{Pc)bStwo=J!W z@-=r%z%a&9mkxE#9+!Xm`Su`g_k!;7tz2v{1j(i2j*k&)WtwxWACYhj0BIs7Q2NIt z&yRDXPFeU-?-7bzm7qnbd`Uo9MIZ5`Pv~HGDk+lq6rnhw9jo%E7_ZR6?4oO@Eknh% z1D=>LHA4%E0iJCYYe&#$LTdm3rs|y8@4h)OwS)9WEEQ=_FcWZ6IDk<|lDY)njo;au za|36Ggu5YQKFUh=yly)>KiM!aso)I{^!k))1!iBy?KCWik#HRZewxjjJCX6mVcD>X zAsFlm(wui7@24TUdOcjLL4(zxwIW=U&lDEcl&TnTHK)a)Tpb#W`lO`ORftK5q>08^ zZ|!a`p*)gXgJz%pbrt7QTM8KJ2ceTi;R&@>t89GFx?7XdERueVK*+#xh!K9aXia#F zjSI#n2GHjT-o10gS{mB35K!DK$FUr9$d7Z}8@GA_o3}jKFe>b#V_@o3765w4(chAG zrj9h4R6$AhT*t(uCH^3DT0ee#$fqEVv@f5*us4T>M%}Ij`dU>H25jtUPEVuhLA$o2 zn0w&;d5Ypo7fF#Vh9EhdZPWH-A{=t$b6%TT1U8How;eTw*~QW}&B%2ILC5#jj!np3 zl%IGsIvx-&w?$PRgw+wu^PuKIfN$mqaoBcJsGx%g*(5!*+Hd`Svj>(Jf;p^?k9SF* z>2!5Kd8Vd|H(IK-Z2EJw#6&f@d3coeHJ+&ZYuMJ*nii_*lONp6cbEyF<%GCKlJ&Wr z-7uX+{fz3gk;GK8zk+i6^lRC&rP85vbz`TOY(7JhUZeZ2>L^sH0Me}e#I#q9(32BN z(yrv!C@ZT>&TIdlr+%oqbVH%XGRt9NOOi%$k#SHfg9jKJAqHg8T*76LqtOwC~u_?oM@dmpX-$?3+sD zh}a0rX3i13A=YN%n|Hg+JvL2au13|-xuu;Otd}tmO8xDMF*YA=Cvw5-f!c!gPSrj0 zXiOG>$v~c_2$4~YAtP;`@!C3nK7}r~u?#^ee)TGd7ERKNZPTV8Q((|po%G2P#0}{F z^8U%Dl#Ftv5dv_({o>hysiUs{%vjg^LEK%f_XE2Ata@5ob1Ek`2Wt2WpJ8@2x@xO+ z+}|W4b-Qt|uxQQJGO0j)_-h2wRTOgUI-e>Wjpt6IL4zu0%bRIwkDaJ>z{vT=+s^cL z|6RF2uHbh`BzQ)iQF3xJ_|A&9M~1eSPyjcn3J9Zsm%IcJBC@M-e9FseH{XmPRxD% zrvIt8cJ~W*e0Jt{`TcH69SL48!QtqldKUiPnxJ2)Fup!#!P6=Cziz+(n}TgCJxgqS z{5H;W#s?L~ohp)OOqB>xI%WJ((nkW`p>JwM0^MlnAq@=?@<}k^H|8*1W;y^xH)iWi zEUTf~TXHC82J;S5NcpWo$eyQ2FQw&FdJ>65z^)#e%aUabK4=3$!as}X`Q=tISAsaUM^}2UESDW&s8JF91Aaq%qZ>E26=GEwrzRO zE}=zeAC}$xXP?wtlMDB~=~tlDv%ov<%Y1O;!BA3Aefc_<9D{<_6l=+Y3yX*cuE}ir zckV!`pSM*zr#wT0dVr!iPl91C1ZY@Th@U|b@v@})|5q{ZTDsFKSSL8Fbp{OB3xFoi zjxs28bumWeDiV@-RbO)R9TsPVDwFuW{^E`p?EiUd?&&XnLcm%?r~5|FJ{#+CvMGe)43P*R;3kty{I4 z`qcP#;~M7zZ4W2C9tY;crYkKzRtKoLdePnGy=@kZ1h~C&>sHdRH4c`+6C4~O>ZkBp zMeGbnuB|OE4NgLBId5P%|G>fmVT%5Ww*NMV4AoWJ`v+#J`StUwyNpE`oEa8L+tc&e zSG&TM%&m#Z`*aGI|K$p&*bFhR#7+*Xi{o^$GzDu;ihJ* zR-2IDP5Qf#qaJYf_Ln}OweYO_3~LYqCAmXgaok`pc@pJe#kgL*+lOIiznhWybOJq+ew|G(X5$n zh%_JnS=4a15=tg$83H&fkC9~OD&!eSkpuKeviF$7Q+P6iqi+Luh8n1iHbP4$_^2IyJvz2;uzvJf8@-FGtJP{l@k8nKUnz0Bp{*$} z0HB3BKv%dTeX-BD|IS4GUncyAla^DUQMBXDS)R|Mo(NDonq*eB?$C?h=`)PS#`BGpVFHCOT>tZ8{td{R*hyDg>F9- zhnZS!#k(t=mN8xq--0JGdqzXOwZ5HxaMaN}eP-H+j~@+@R+KCz_Jey>W(ey4COxKt zgH`)~Bprz_+^7)IH;So+?3;7&jxIjhfvJkrF_fOSIQgZprbfC*V|x^J6YWAKGeLn0 z4{Tn^SwNSOc=S^r<$u%b|Gg{u0LCEjsv(R9KA;j%XsgBG8f*SxO(@RE%c;pPHm5F! z?tlC8P7jnuPPh-GKf#8jbtV!}#x`J$gWUpXq02XKE=W4ZHP)b&e|2BzfBANT1%oWG z(uh5-qp+~nak9|vg=~-1y?^rLf72M{zMZ&r?TG>4eVL^drUZ==DUe$~zhTJKy>Zb1 zBIt0}(=2DAW0BQgKc;ZJ`NKlGED-^(7NwR5>=M``P_ca*~|F~(u# zUBynO7jRkpgX&!GJo+ST4)g9LN9~<`(LQ_heS@&@+T(8J=4PT(5YfPTi`A$S z^j;xm3aog8RjEzq&ckN6O^S5K0ILO0IMUR442*~En?3XEk??xL3#6IRac+X?T# zc87a7R8+go;hFDx9mv?Tbn(+kcR$Tp|Eg11wr=QK*bD*RzB40&gO!~|iX!^m5U+EMa_w0v> z6W8qZGJhO;WrnKRj%BXw!x;+}jDiSl1j1`!LBZFwW4Z3#B^WpMi&1EY+I4&Z+zz^? zru&2(mP;K-k%iSxdp{r>Qr5Fq;qwyVN-}=p3oKvtmFZUc0f{q z0FO$6Br}nGs^abJ)30AC{a9JnXWZcGd~$Z(C5j^vOVhuRyce}|Qfz-TsWSD9Po(&A zJXB@f?;uQy-c3<(&o#(86y|yo9$K3b2hVmc!SIJL5*PADx>}}^sDK)tr;m2Swnju( zDO8LcNg@h_u10@Sh3p&A@ynb>(Bz(@oD2%i#%Vnn8=8B5Du)H>Agg7AApZcy9rwH( z$I<^!DIeQ~RADZKQeGtdr|5Q~NAB4GuI|8_qnEEb)$5g!9Eb`uzgC)tP{Na4wV$A# z?LpBoe(C8{*WgbDE9)dC-8~Xr*4cCQ`T$IMVj|Mse>E&nTU&BAyivJlo`&ZdO$&!5 zRGrv$Wf93J+TVVc#fr353EAFuhly7&94q5b)DGR>Mfo5jCQZ)QS&V4*GdR2W%k*)=D9hucoc=vMtzKp)!*DiykK@^u|dzCHdjj}Il|+qz^DS_NS1Z0U6&_Dk*A^l zdnK|5 zr#!=YzQUTlecoi7KMp`vK^UD#gqzf`~=jpOZaK#thIFTNDn%<1FU zybcGr@QR=L87x})FD<|`HNG+KL77C|c);8TRE(UM``!a?Tb+yCf9*GO)d!tDM8i$^ zhJ3J&9ivM|rKpf0q$uK7VCY*-mQkg$)!Dfwnl#O3&BO*X=-cyFspGFL`VL;L_KNa* zlaLaVi+H^bd~n5T)TCZX|qdjYX zFh3{9On}fXXE^l$W*Sy;s7C!xQlN(drP5WYajvms#(@hLlO6EkGGJG($HNmoZ-;IC$zIyfQAb0nq(X#-R0Rjw(#v?GY4z4#dE<@p0qIOPb z4AbRrG;n5j8QmKw`5L?XB)K<_*!2HbKOO8SCimK?{LfKJN~ET`x_W)2FjAKB+soc% zkf$zTw)o!H)3{BC922gDFWLOHs!%9d6IJT2?krVv6tOVSs^h$A%K5YF4jyYXJn~A|!3(fdgx3!|d(v>^7Q+Hne%vZ36GV1QI!M2%i})nS!Y1Eg zXYzW>{d$)QQaW%guOn}UC+GK>2EX|A>j%>d&%5g27A|^F<5l@-=h{>ei@W}&*#Kt{ z>L)-AojrHSI+}{mVD;!jheUHj=V2l9*3b($?qf-DBXSlCqD6LVV?JPFvc9M!xhB%z z9?6d#b+^}NZwxi7m}Ff|L3D_4%pX{Jym5h+&V(0V*(m^E<2+xUNPE8UpX0Cl{HoEK zbsxQX^DuhTMSJhJPuqz^+7=zzw%i8QX|7*QABL1^()R6Is>iA&_EnodvW4og+V`s0 z)+yh!hbbROp$%b6?Zyvq3R-2_S|roY#M(X(FvM(Fx1+muP3ln?AWY}W-`4vEw6tii z8ehkmeh-zpqT$Xqa2a>J({Zg04~jqK)~f9`%5C_0lXF2>3tp`C`lHOYGyhn$@J%kePf{FE@g&SFIP-j`eJjQ~ z_eHv~&PK1Af~|i1iGl~zk=4x2&+BDZ%5;Pi{lSl!=jf;s(Y{YLD^F*ipC897XDdyC zfUcA?s}mDlqsl~p&E;H00pcfmFEw)!dZ@l_OJ&{Rg}Hs8&}E|^M9b^srA4Xm+3Y@61@74Pd%-Xx*_BxdyN zxpM={?ZqsK)qWGZ?mUjj|JLg(XF0l(80jN=X)H+d;+{BEDhC1$Kbg9ASF0}5cS|5* z6kpmtClUe$Hze&>MWMs#4TK#*T)=-V7s*@FMj6QG{2%pr=q4wycVT}iqa@2@ou%!u z-&K9;wQ1A6-PYPM#j6842GpFcRs6}eQP)s|!lTuUJchM)J=eWjhn_|ruXKA)wz{60 zVsW6SQCQAoovM~*Gu;1fp}N*_CrJOf;P(M9yBl0{J9F6O@W#H`vtN7c+j;(;$BnNm z!6{}hW-C1jHOO~u%2_70I#TQ>I_B3oL8#w=OzgUb-Fb9IEWI4^j=H0uy^!F)`3VWV^TED@1 ziytvh*L)71|73gRH#IUDTvRtAQur2{c(popu$9QrG{ph!v=qD0n1c1DPOO7zCXiW< zJdu7F;B$alXRn;nyZ5n$mgKB1HDnA@$#RdMx!0?1H$9oP>}JoxpLvr_g9DAK5hAED zf70}z;9#F3iK*Dl+>N`A1_dw6T{UWlJZO3fgR~IHnderb{*ljc;6OW66PO`x~%=(8w=2baw5Jve9?X zSP?g%2429;T3v%+W0|{BwtY;j&1k()+>H5YQFifLHg8s#UV$;f$f_j%%8&fpc2lMe zzx&;;&}h-G@b|x*Z`^(G_uO4B*4+->Tx3$?M5{CUrT1LwJw5I2ws(T{akYYmlT}}I z(_h_uq{o9#Sy`4xpOkynU1YLyN>+Mds~g^>#r^*ZfA+B~=bwF@_4l^pc&h#^^MZM9 z8h;!(oY{BgEVQfu)oMd9!#eC95aQ6#L0W}~TP|=}!l_IvO@{HJ$~jaKj+6M~rk@iY z#cYZ$%^lxh{lR-)S%|(T zbbXn$G80^z>xHWG4>;$X12#oW&C+M=(?YWE7)8f4LWtS}!_r4U4^v!P>|K64m2lw88j-c{W9Ve-p zx^mtiE3Tptm)q>7$>$d0tPxxhhP#S}BjvJUbu$8{_Qch)y&uRYk#Q;F-mBH^lrMTS z8E3SEiE0vbBZob`QyXm=`H7-c2rGHiycHrYIO3uHySAXO_2q$$K*Z`2>>`)H3baD?D#b?rtm){ zIG_n<6G`jizc|L7`1}>FYAwnl5#nLQILG)1gCDQCUC$E;nbM14IygJVil!?fsO^ z{$Qhih4&HBgB^^;qpX5<*uZhB>mx3vP6|*~yM#_nHZuO$d(p2S%PS+aLYa?wTv9*r z_h+6Wf^-W7k^c|pLDsJMA5*p7d7ImWk78C7Ga)1CPPf_Ub>R3W9Im7Ppn=LWPV`2E z7AraoYN=F24(rkc5{=1qC{?41ex?$Sq-ElnV&E-dAK&W4M!p}v?-LnM&8wIZocowm zO_*&}Umn{C3kwmRa)oJYzpJQ-Kt13%1$LNu>ANcK@EZ?*@}3WZh((XwFB=;Rh506~ zH(T@@bN=b}pQBto63fdz>^xj1EwZ1O4H>!{t5h(|vxc(j3 zvm6Jy$98j*6L;yGTQ~Kp{@t$Q?*IA*C|UCOar+T(3Xe=Pcil8nhBlDFquZa{U~Qx( zh9cKb%iY}E2Ece_PsV>7fM|LMseKg_oNw)~20$2BZtWOo6u~Q#W=u*MQAH@U zyQ{~>TCg_QW2r47e?5|WYHw2Xuul5x?DRsv;ER-TA0Qb5pOK!sYHVz!kbladv}}{> z{6?99(MY`-fAQr+n&NnRX#2Qv-`Obr=}Y~*TCZ0_Q@&U~LX;qlGmr~hB)Z}G?ZF;M zA^aHoTmo#@_(`+o&BvddzxaDLSG43*B$M(QUT5+s(hVA#m3w_~9y~bz_iMZS@Avov z%I1)e_SanEOshmuaU;b)i;L;_(xq8@u|)cDW>U*m(aG3DCYvU#>BLPVe!IU;UFUJr zJ}+;^#$tJmY~ABLLebnq3`;R{`RdgwibTb7ry(z^u28m|JsYvenYn77J@Qg}G==t$Sn${De898uzk_0+d$kL8N)hq;g)LD(?GNnDpWs@UBH ze-Cy-VUV*#O*B=I0&YzBN|>D9fT1%!hJXOZ$9VZp7rn{%dcbpp^_cRg&r|`DM7c z^iBn9y1b?@@c+GKrUhJZSap{^yS-kO-0M;Bp=Y}G@s}f9__jF*h6tT6%m#{G83e}R zAS9Hy8d0anm}!VeKCueOCiVcaqk{g$EKENX#57*6f=u#Vj#4iQ#e_SHiw1HWs*?O9baen=I%zO zFdeV$#Ep)SmI&@@Ku^5QA3sgf3YMX`@&9U6HnDw!b5x#PC#J+K^s(lm!eTW5-~O$` zQ~F`7k3{%eC&T$;!RGHn=qv{enEK_^CO$WnssQhPf4v^{yY$H6#JC4fF2C5UO{w&*(K_6oN@ ztFhs@u;u|TjxXDDJM|Uk_Gr`w8XCHxRw(E*Pk|cc&rR<%bLPw~R#Dp8`?qdwfW|n2 z3xs)hw}!S@n7;ehukQ=S>NHw>=h{N|SQ|YdcW5Tn-JKUcynVYM@BPwOMV9n7Gf3Fx zWu>6`tG+QY$tLX#TKZ>z|6&=?3*8{|eV74y&M9`muSKrEZ9Wb#Wl9Dh^cXS+V)N&c zk#vaUmD?{;d#1lS^Xpq@l?ZebVY?v97kl!c%Q;spY&>_1j^s{J(N-J1D1gc_uzeaD z7qhaqLdr0yW4yf&yW;~fF!eQV5$atYI(}*-seGq*k<>Z${`TY7i z#2y?wuP6P-R;wuSK44e8{dccI%YP1c{il+~tZW9)PBV92QhAmy=zn6xiWx!Xvo|`} z?d`SEL3=+1Yy+jFc&gpJ(2tMeCAs-e78}tPqsGRDuvYSlkHoM4VVmYN;QPxSdx}h1 zwAysY-_YjFA{)Juqg{@u)5^qz?uQ;9nTZ zLHs9|l5@N1b|RZ%b9$_t(CvdV=SxM&2U@{eCX2c;9}6SyQ2rI+!sez<)VT)MZv|{& zRHvn}&9kl-?G2!G%* zars9+xl$@ho*c6lZqGTdHD|6*|DVK`yG&6v?c3AlPO}HyXPU2)w~Ed!{rGXU_cRV% z^Lc37jZWN8<>NdlUsxB6dk*XsnRPL*Mu)e&k@3mxb@O2T)~zR$*4NOm^-fx}oMU#e z{i%^!$*-Q6ZTlJ@n|SrfBw{)T5#mjz80ans!eXXtoLVYqLdSnR^-Nn-PKoJBi&%pRGpd3&xA`Zl7es?Z%cdQ$F7 zGA8=4xhqb_kGnhB#j~%s-7Y7i_8=6j>bJk9*su4y`Q7T zsP3JyllVMyZteFUT$F1>GccH@BmL2_wx0cM^g@??c%}jS8}T;n;{>Ny`<}e!m>f)4 z9*lPo7nUe=mf^ONTzF|{#LbC5Lq&$cH7w}-BI$HoxA`+or}mF!V4`B>6;Z?Y>0YnH zncXRJ&78ZvAGK+n3FoGxX6NYNUxpX|6~DmnV!F=~Sxv1q>^*Kh_FOl=w#>#roXH6R z%@RZ{KK|s2(WC2&5mWDJSYypmo7&#peF_MMdyZC+Sdvv)wGyBkN9-|f%wYqlZ^?z1 z{qb*aGO}6)r)t$n_W^uCCM{A^$BC51s25l@{?3ePEc1M!|Nimp7i1rDAMeka?lKS5 zI}=rkpX2qb$4{QDst}t2%CDw;!Cc_~_4kkW^(xarIFOam`b$HDmQIO&StF9XFUKMb z>LO_c_eYJ>r%xXTc4elB^2J%@-AnwHP9u)xmlc&8>rd@e=gy~XSBRUHCCjd&HOfM zWty<;*aTKSvES?8(X_XKbSmU{cH0mbcn~Ft#5&HQsZ#Z&uN)R@vlSBom(v*NCUj{z zRHE#?ZG$4~FD#>Y=CC=0Q)jDUbG*}+Vd5ccvQd{*KU$k%NV#UXxD2108a{wLwkl>6 zK?f1ojH4D+iQpI>=5%+;q}1!F(P4SB7n|7qbs~1uuRfnYQXaSRzOwK1yc#Zjt{+zW z^zmZ{Z~*JAsz=C(g;9j+v_Jb?bJd8(7GoZ!m?1W6JAy!02dUV>}|8=OUkz z9mWE**IB)0_39YjiX3~0dxMfqW~NL~Ej*SHPOHw3(eLfbiz9g0QoPM7ZKTHt2#BCi z$|VWMN~|*1clX^!i^0uB@F8h#&hXWPf-^YCnqn*1!WG1!l?M>JKHwR(=s{_S5E@@* zG$YqPvz$C0my`?~8*8(yTS(UzWo4G!1;Ez247m%4$?db(*4(Gp^Si$&Rs9|r>FI4y zayTNa$w469Q5aD(^6FwXhb7-E;P=RPL->YJLt{+-cUSHd$vo8}&h^!UjFVH7T#Szq zDWI`ZRmW@D^5vnOjUl(}=Qo4(J@q*t02x=?YaTo`P%N8Cs)v~07Zw(F^ac;jKk|V1 z*IK;4+6wVm(%@t1Y2Ziw!H$|Voi44*f4&?2?}JvNS)d@0OO$UoC^!xeymVx|d^k-@ zi>QphzJ32b4#9>>1jpA{3q-)jkLNU2T-n-G*Z>o(l0!qcU@5SIVlS5K3HfCbZ6brfpvH ztoJdmemaoYL2S||7&l|EcG=8qZiz8$^QiMWoXxpBi{~Fs%$&Ww^R|!>3yMhGjAKo1lq#_#V|1_TuVh*BdMzvt+QrvY z*dm)mESt;}C<;bxy{?y4a>!Hbd|^y$>kPHi#N?^8Axe^NTatWBY8=2|kjn`4j=ObN z8h4wyuj~GIVdmqHJ)~*0!e}!qW4iwN-|d^%YkDsHlBL`EM}tOqQD`0L_BAi;l|!9F z6P5(pHpXW`52cVeqg!}DPpKTz$FQnX%ilxa8+v`3r>Xg)oBzx`*F#bPV*ehx8P>man4Id;hI5_l0N5#9TmpK?!*m5ZGJx&A{3AmJ?aGhLKe2{OGR6ym}Mbo7FQHi zwcX)5{Bq0~iZ75%PWl#bb;vWZTU;(E?UTit8hr;3u8s>=6I{d|l z3*_7v6Qf6?a~j$I(gM($0~1Er=#em)wD5(=uf@4oJpOaQuCeKbNFV;R@7n>Tgh7BPhjRXUf$+f_gsV%op z{R?#+vPury4H!q1vqGxyX+OEzEKHU(Z5c_0F=- z14GcBoHXXnf$nHMsN)9H&-*VImog}6bK`j#X9YAjaXN8x=v|ebX~}EGO}W{gwAQnv zn}H8nAUgy|6bH%Cqer!-Z8SN_jaz)Fwa*2teNyXDC@8)drz$xz@Wr#pMH~=OU<^5| zHiZIIYL^-{YA8`oX?#~ru_g+Hb>q2+PD8DPzZWReD62z*_2L%*N*2?fV%0730a_jk zN4*P?Z%|;VMWih2+QZ?jqMVg1YUj|hsF&&VMlyAXdyi0t{kcCs&FB|s`0B5uq=8)V zzPW~pLxQyYk$^`6#@)Q#N@HNG&D`!585jS2YtIP%-t`OJ-x@n#PBVIiV({bZP`kXI zJI{m{#l3KG)=mQpk*<*A^HA=MXtXo@BHI)5!TUS3Z$Fw5<2mbXchY*QnS9X;y{dI7 z@G!B&#y{B%2W|9ToSN_2^TX@|y567U7Wxo3_5RAdkm!_G-wvmx7kpUwZA9Ls=ifjR zv{WLfRU9YInWOXZ<(+LDS29C_RB}B6u(g#G%$~GxnU~cqETCwc8b`H{^NdN!8oloa z#qv6jBfHWUSbdn;&;GpglG&?`MC@2pH}Z}luGkyuc3HW($yezXhCWMq>CDs5d`K@# zJCo=!?~l7R?!9M%WFG&Ra(^XCU2mzO=dE<<` zyqYMQm}3t-YvE|SKz$i3|DDQ`;F#E6y@nk6)2Q#5KW9Lp3vx@Rgj-+}C6ryu@HgFx z9oI?RD&Sk0KkyAzy116S#EhLqiDEbZr${v=!H$#AfUpG7sFAtq^74Alu*w#$M|AT) z)Xt79REwq5daQj7aRHMgweWrRw>pw@0{rV=w^sJ;o;F(XT2H5P{sxv;*RM4BM!Snm z62l;2>%r{Qz!rUz@2wzF?1wk$cn}ar?)?Z~Yvp8HNkHv2ynoiRQfJUpAA=W)T1#kd zH@bLn6Vre0IK!Pl7psjq8sL*85ufyr%VSbzU;1a0MGjjWc=7yR1D?dU5_|~fNh?gE zGLVcy$=V`cp_o8vh3U$TjN9EiwY&%YNw#;rn7IM{?0Qsofz9&j0A@_=)}=vY-Hk7T zo}}G3a$PXx{jGcN4msD^bLPn@pYZo-z0-=GOw7wJ?_u3KzWE^B2wd*Buy%2lL(ZH9 zca-Yimy&^7tU9W-(8HrFhK?9v!5?MyHUD_&-M7cV9@9*Bd)>e0J#K%uyXUm(Ha(Y` zb1&^=+YJtOrgf&M_MUyc{I5jo$*L}U^&6c#F`}@RVI>3iuWHx&`NBET`@XbcP@Kna zUfr4if`SjGYF6F`_U|)WI{m{uYr6FMzXV;99*O3t6(s&&=ihYPkz1eYwKV>4?Zu%( zhnyH{r47r-#1?qxmFQv4BYt-5puRA9$y_2>~jFhBZLSZ&xu%6qcV^(;> zKQG@ds?+y6qjegw!pxQ|Ny{n<-mqbigM-7KLZ(Vx;$GcINMp;Ak`glG3+zW&TaLT_ zQ*wTUEX52!Y50W%0EBS+la7b4jt>7`xm@ekUCWt-QKb0k({-HrbGztgh1dG$H+KFH zip&g5l2B98ATeNI{=MTWiWrc^+>1dY0-#s%rD)ZFg7-r)OmV%1fI1@9#Gi*oNYiv> zf2EiOB%uPZm;B3eV=F?e049ilWa)$DH6-zlG~_195iPBCKMVRK-7s!~DjX9Rq1iWsUVQv^_628y`1R)W?HqJKw`?UJU{HTW3Li8lLnp;L zyYU@S@k)S|csL;7+G=Z8;pa}gQQyfp;CaNRf9;uW%F2p0t$)P4H*a`p-wFLgH|Jhm z6}>QI^JX)Jc+<5U^=eAg!Gk$SdesyT`}!JVIQ54`jTJB49!UjfHf|RU4e-TVK+*vL zI34$h61=jQluQtbM%UhtPH&u?K!vmi9TgcDKvPG9F)Yz8Y-2a+j7GEg2B#ex;r*^~ z^1|N`RqASLZ4~K}g68$mczU{5`sdG|J1O*{GD%hI&MfVpebb&x9esZG>Ir)^G)%ul zZW+QGp`eTY*yqcwKJ}uffzzodOy*ie5;;YkFn(LMkk!5MqMMtWqNL2tS7*&pa;~CI z!3I6rc^CXPAiQtIDHev(CZ#VYuBK+i_^{~B-#OhQxI|@r(nr6|9p24(rTMOi=*?cr z-{{r(>0*jN<}vNB=2z@{oc%pacDdbbZj0&)l(bGGb^d~!v_0zjCkS_LC;+_G{iDEL#+(3WJWjQ9>Z2oInLgY)nR`C;Z4W zcpzN+K`0@mM&|6E(}U?BP}0QvW`Y5%7O}R1b9aDDYcnu3bUxU1-ih$BuX|I0HJ!Rl z1t0D?*hDv~>Z0R1v~T0F+4_oYC#*9?{4CoNxA_Fa;IIU;*TKKw*nK zS)9mXCKlTcghV?uI;d*O3RHY$$wx#eRK2`0UycYFUMF|5Xfu>fojL*T*5F8!hcY5A$IL+hE z%@N;mwEBCkX;yWv&ySK)o9lh&TyB9iP;M2oa?Ln-(m9c93=+Fr_(6g(+pQUXG6vEZ z5?&>wbc~IjPN$eRj^qF3*Jye!f7!cv2K%c0OM!Bqf1?h6YAtni z#e{z%T{ZKn7L|XWx=vC=Bw{jU&XzQD#}RL+CDf0#ka7X>ou*cTTEVe_FFwD#bKq6| zo@-AA&bGGXsX=3=wyf^tnN3g_RYy@>^G-6-^-Dh!la{=*HLzM@iD}qyn^s}ru{Q%x z_<7vaj32gUZ_OvuiySBS;LxrL40lZN9jR;N)p|O--zYbXM_R6w%t*DgV?AZIQcuhTVXi0I@u+zxf zOZphUNPoKbyog^MJprh2OKysZ(Gf1}NX92E(e+K#*~9>+EK@UsEc=G%DYizq(DnSD zd(*zE7emD=GHZ2Hy9tCjO6F2d3>@l1J&t-iHuD2Kg*HVQ5Z*eBuDsimX2}#jfyFV!92U%;>V0?Pm0OXPasF&3 zo}M-_QfAAN-4CKm@2iT>l{*;Me2qrE&mr4NSjl~GTlRo@U3z_m}d%{iXK z*W|hQoZ3}&&2S^C1ZRiz`>=`o(VZw=rVit_yl{EP^)Sv!$r1)w*>@N+ykVcO(^qJ z_pbtoA?5&r9Ijs9SXrz^MH@A*Qbpkxx{pR2kQ)sqC_ zVXagY;w0DvQpuqe;EB|!?3$IcmoC-7Ejq}Hqf*8vaBqvQs>DbdUaBPWa@vvVqSPmc z7<6760hllhFe>6+}e)q(;TNf{@HSYHZCskA(}hjOL?XUSv~a@q|;+Gr>&U4;;u@Wqsza?}k8lpTB_naXQ zQ%LyG)~+-k^+dsG?D3>_OVgFRLA_e`U$%LBw`uwpK6Y`huYvVxqmqLX*cr*1aF!g5 z2S@9uDNwOt{CYLz>$h(L0OR*2yECl*L#XwbhzMU41XnIyT8G2SjIS(%q1c!qTek3J zD05PnnL{s6F=v!q@5PrihlG(boQqrWHrJsiFm0>=``G0m>_31bxb*8EJu}thSA~0= z`@#x*C^;Bq%{kXyDhj6;A>Ok*w%}pMP^%6jCIPlw-)Fjy`nvOoaj`b=D=8Yj9!G(-V(9&%+ww=4K z2IE{GpwqwqWS!~R8;Vh|RWU<4HfR#CFM$_BAX5$rW}U~eoo#85R}=lV_^ejE&Thq` zE?hDvp(dc)C#@ben711AX<~vi&0C|^t-JN_rlS)4Z1siUmv7_9e?n@7jWKeKWPdit#|I;y%uKW zKTSq0oxX*;5`B&O=TTLB{|KC*a8L!Aqog%PQZPHFxcbLxJ zO3jiSCVU|-kTzYuKmHjSXtbDl;(e*I{GU?C%I{Cn)No?RM zw$?+==zo&7u>q;&ao)=y7|E~YD`$S-;1*pd83T{ozSDG?cpy~!?*|WB(NRLi#pZm? z{140(d|L6PSkFX*#P0Iv5Mdqr|8})=pE4QWqtsIEapT-C-v0vgr-xSk)18w5HyIl z{Sm)Yy0a4y%c=g45(!69S<$OXs{cXP zPLxTIHW2%wL!zaY&4WBuZ*tM(j_up4f&ifOy96{VL_awH>`hg5T6!eWH^LtGpthG0 zMr!Z(zTBDAedgQLIk&1Hin;IyE?zHoU8KMUgdGz4^HvfJ3JaS`!54XE~ z1&|oYsi&GAQDZR^K)-xPo_G%KV9kw%LQ#7VF>i#0)~5gHzw(DBTJ6RgX!yIqt5(5bLECtaYPY83#W5w| zW{VmM`3e9(0?`^ZIh}vy#*M+qeBfXG4cE(OgH4jro)9*YE`TzMjd*45-MH&3W3yMz zN*EwEUlw54$#r{;7W}yt%FARL(IqrQNzi+(rtNSZ0rV{fV^W*A^~Kkq_|nBOHnuS~ zJ4|>db1tbnndPC{j2;qi={9c6lC-7xqjBkHag^aTE?d}gl#vl%T;8aJ-QdBHoyYsY zd3R)qiPXH-%|HYTZ9F3E;>A}Ff=w~*y6*f38@>{gZoAR=A4lPGY%{D{T{;scV77$i zryNRYp_{ih+H=JWYZ@d4kXyF4#5T^!i>?Exvj$zGbH4s-@W$dx`Tz+92vB=b6hwT2n=c zHm>^`Sf-h&9?~topy3I(6*G!1(g#ADQR=6(Tszo#zuMuOKd%QSJsH03V&Z@w!Li+@ z7&qbHIY4M9Ym%u>Pm`P`Y?H8S@C$YvVHG97mx@B9FXg^=zkbc7ep&i0dJVv$nw`nd zxQd?7I6ntsn_cv%DnL>I<=m-HMJ_>~!cS~&N-r8YyxOkAITuThayU@9+#;x+G4oNA zkDLoM>cH%}!PNis9w<_)^Ba|@b{inTB<-AG+>bsRI2muasXBgO*oI;XRS6>|dOhBK zg7u!71^%ZDvcl_H?<*-Q-8}y!d73aeYM?Hz>oV>4AT4Xh(&AZx(D@@cR~&Bbx1^c` z+RTz&*eaJ_hY@}Mb!-lyIYpY)#i=ETtek*!t-_qKMwF0WV_T5jMCcs80w>P9%)i|P z&0{bIi^hONA_RgqMZY-EIH>%j`sELej?aflG~+InxGJWrMKX5o@6+BVkKSNYNZcMm zyAm$_#FYDN1BuzU|7%tq32hXh{Q?)KBLzF{VOvgpGv{@a;K*c1I!9T>l}`KGa9VN< za5^>2YI-9(TVfR@^2ODQER)M&L|9-Fm1#x)1I(`QURq09_Ts6Yaxb?sF>}4!Zcj=eIWwjOn7fN!AOEyZYuxVA9}0i${lD zbeXsW6j9X|spvogydp%8k+rEMX}p}T9Vjx9+(x5sLU7(yMx`X(`eUN|{yQ>O;_Mkb+{R?!Q{uj00)U0Pk=_?`jI<_zA>eDiO$(f^i{PkBv>q zb;Uh?DkqDZXlTc68j4J_6tToh?O8jGPrJev6CLfRI@o!T@Ep3{5KDvG#J2!Ulde04<<5@7WOD|cJ_Wf+@O*x9Ko-deWr)JcNPB?2Bfi=v3W zaBb~o606|A>SSi|0I}L2>zBX=Md)nwfws*)Llz)nuOWT~)Ewe1qrQZ8rOK_x*(js; z=v{^&=u(P>mF8~g)tWN+NOA_NNr)OQX2Hi%%c+u-hj;!wp&siZuq;Mz<0DkTsm`ne zweb@Sqq|Ytp{&*IzksS$0wf4`ml7?H)<8m0IiAHuw`b`CmC@h!^kk)Tn0H?KX{X_* zmnloIhRIR=d6zfOR zUF7&9QyH|Z+xsEz8Z+l$U#efN**A8J>Cb;A2XB1fBqaalCY*GVYfjZAVf)CAeRCb# zuKZTs$+2RI!sX-@^$O^uWgE#YiFV`XmScESq!Lsi^qG6G75Hh%moQrq^6O8x( zZujmQJKZ#kx2&K@@H<1pS4$!1lDI!2cNV5Eht@V@ObYvLBNY%WM0FY$YK*v?*O&sO zh~}-eW8w>pd6(V~b8?Pm8gqpVwX$j;i1rb?yW~%*;J)~SgG-Rd9~DA7g_>I}`|6D3 zg)idr=PEj%PvobD?b#E=x{xSCoTNg2;`5#o-$!gNQ*sk0^_Cb&iazsU!`6ehB;2B% z?*I9oN2UkWk3^mdVoNjXSB^_Yr1aEvQouTTQWwzAtinhB+H7-@-kel5u;#&xFkoYd z@|!_T`*~=Z1gnep5b>U5WBosLy?H>+YrFP;N2ah$A@i^d6_Htl4224nl0s$;gd!Y5-oO36`~71-`+3%)?)&?_u5&of<2X*@ zj-W387uliNwH0g3n1Qf*Z@Wm9p@s6>d`*^5TL@ufD2+7;|90y1w^SU{9x_AT1dr(j zaGbb|h^>f6m4%v`+OwKp?`uxd7lQrdt0%hdoJPVL@8z%W5NY*s(tWLQ%$Aiurr;#&8xu<(UU(^+n$wYIOa z;gr*|WQ(YoPTADg7(0eOqHP7uWZl;ghetaG>9{1XPwKP1ApR{_KHRj19ZaBQ=P;8t z7&nfFqZ?PfmY(9q4#T~Ew$6oj7jy3Y520@P!A(mcH5?8pM&xj}S{01eHXnJ!;` zQu{Id7I zlaJ4&*u*o&klm#Ac=pWX$USdPAj-OD?8&H=4o4sLaq>y>(Z0}Z19UJb~S+^Owx%lIe5<1qk&fMH$w>GYlOpnUYjZ66Nm z*Kai4+Qt&jQ^K}zzF2~Fxjp~GBE0qtB*6Lt^p@x!CuSb?b@`-o32>gVx5)8 zDj(BhgHZuLTBn#}+?v-m4^KR*$GlbQJ4!ck%6xy^nR%R{B#$W-;6GbcL;H9y5S#N!NpnC+3*Fsf#kKC@#fynoM6SN_AaO9cQw9WPBgnMJb2{a< znV)q$>cxFz{pd+YuU)IlHS4*yJf-H>8t(8BekZn7dK4DzhA+70Flq7ru>;=S%`dw9 z(`NOm|E3KLPHBH|&@rxpaKgp-{_NSa5@M`aT_Dz4LRO+_R5{zrw{h8m`SWX2t#&Ls zFsQ*y0l@u}72`WN* zrc&fEWCUC0MsK#^6MMyo3~DzqT}>J8Ru{>zNX{m zoX!wJNAU3v7hibip`K#fSJu`;a(~QMx_danQrA)7fQ&5ddOpv4uS4kf%xF76Sm9^Ud&PgfkCMObk)D zi_(ZT1+Yp48p3t@CO;I>F1!+_1gV2 z6v7yzqr+-$V92CGbaUQ}a()}xIL$;`PFw0Qe%{>MheqGt{yH2pFOhK#b*t!h+&I9S zxrb=LiCjWmgW?MGOM4yttoyGTd;+A{bMztgY4xaA?)b7nqLB!edOs$e=4dpNN);- zaM4KBLL8E{vi!nM@fR#^vnHIGc=L`hp{A#-)uAHYjdd>MdKzwvhXzovfTP-J%&UfW zVAkjTlu>PkgDOiVLgLcY?u{a2{?-t{btJgZ?yB8u$}GtF%5f`BB&ads?{pzxmeO%u zgQEJ8tt!vRX)TVU3PPvY0D6i~+adRY7R^wG$E?N*-f{GFL`E-ac((DyJnH{HM)8L0 zCe}5q3Gj!KJOE|CYee1~0{}%w$`smK-ngt<6lK)Rl(lW(c1a*C1Z98secVQ#gu%9H zqnOi)H@t?1hP-XXGcdo)@&6DQHn9|~u1Di*2RuosEwItAslR_BP(JJH#%G$cMaWws z&3i9#q=Jg^8*hSlbNLfwDH&Zu=*BnGOM3(jAaxW7!qVI%t1F8W^?6H!*|6+`9hCG% zP(h-XyP5MvvD&Qt-0i`GaiAiKuuDDs7)7sx2ndF7zkc?aaFX^F&LKiKeE;j16rRG} zsGomtD{ll{c$YM%IlW4EJJ;5>9_25&JZ#Jiel=^v>kGog4s8G!l}Z{L75@EdclUXu zl>J4N*E{=;eU)I%Z=2YtS z**_ofNA^$(lV#V)@AbhXzOH-w*llLZJO~>F`pV7v9xM&3Gg4DMDeRvk{?;$NXJlM& zoIXw~Gd{lenY&X?*>yQ+ebA#%+UDtg@eqV9tmUcyo?HwHx?byqp@~09K(y2J8P@A`IeVzJ_#cB%~tNBe^ z*JWJQB47kBpfSL$1$nO(b#(|3P;WOIBlG2|A57b_-Sgx%bH+eM2`(7*AX}FTdrTD_6#fU)viVr)Kx=`bux0RlR}tXHs{=XlU6{LW#a; z6Ner%&etsC`t|XR)wK0A!g9fMeQn|_nb7XSf6bf*aT-XWpH-Nd#%-76scommIl4V< z=zh^=(&3?|oP1*~$|aZgPi9e2M`AnTw`b201zV*w7~C9Jh!3j#7a+D6vUHTM*_$g( zMwwG(n={{}xtv^uK^O+dvo8X#8O9Yv!)SAXI8!GA^Rg%gP#PQ3LO!{BBkG^n5V64jkrUI4N+L1-pQv z7$Nl{+trBx1GX+IDd~l)Dh+&J`FyMsRSls&w!m(;zgnX=ye&T)SJPo(BMKG>0zfk&3@76=d$=M>{(xyG7(_; z8@QE{)Z$Y{e(Od9sh1Xg2hZ*h0-gvuFWT(F>X2=7*%hnV-ednLsh@&^1cMHXwff2m z0O42EdR^#{NoXxVV4!q=Ex7c{qT4&PToF^l|3V1E^=Rw(5DE`*iD(^KP)5nu5R<-F zvNAdRH?2qVr|PFp4eHmA*!|sN2y8+6-1Sthdm&3fm!UDvu`Z=Q%!HX-Clv&dD3`{n zp^+Zno3?M?DD^izYD?!neRlG!Wnj!q^cs)RA=hZ?esRsiv~f`Rh} zT;IBCW=x^ECJE0+5JAyeaka%1_P*}zTH2^?ZBChzO5I$;DN}|Nb_AlJHp(umDm+KS zh&*~6%R@{@eK_>K&fFN9o8NZ)hYnTp1H|Ax^j(&2Wh0Xh!%UYfi5YxApRiv_latsu z1lG>$mBYY!=$Z4sziQZJW79G9orZM0?>|SqzW36Oi!Sa)?_k<=<@sm%85vRc^9@Yh zRBFeO<+?s(OuF>^GHN9;bcCH1V&KzOJ&eaYkBJ*Igl$wTTCt5z%|4A^#|OF>2)8wN zL8-cGm2Y}_u+`+H>!3NsE}KlH<~7*vHcaaHr`J(!VD)0YWOjL!Oah=Z>`!`3SJuu_ zufBXb^9%J7yMMK5%t}F5*Do1;4E&fiPkW%>nT_X+i7J3(M1vq6qM_>>8%8f5_yJ+V zKghR{%`2(Kf5+$J9+lVzXhsV)4#Efz08@})qNNS+Re=@aAuNP00 zbJI$N;th57Eh;`)I9I!?#cyOrG(KlQg0xn4_g2Ac=&uP%oM?(`Z^{Nt% z;SV4(>&9*Rk0aVkRE`EE4D&T3=9vPosF={zSU`yH`{ld;vG|g6G4~qGRY{KXMM0;P zHzAp%?s`jvkt!x+j0^Lv!Ig2Pw{>;{Ns3VnLUQN$m`*njbkTh2(i1noJ&w-MO^j$? z@hBqbSoi6V&QKDYoL}V#1|*{q)~aIcDk8Ysw`1SFc;%GL400=O z!{xe08~hCx{AxI|->7#LQVh%KqI4?aC?5giX1uXOh{{8U4RffSB;K`)7nd1EpKW^7 zUFaP=sa*fdr>26t*~il;2Va_Rld*A6;`_veqz`ICT$2L;OKZLtT>6Rw#(T}IHKqaA zTaEFxN&ag`_p$$2PNDYbl~;D9yT;G?PYMe5v%|Z;){KP?Ima4M|Ied+hO`+(t*cVj z+Q$Eq(WU}hZjQcz{r0H-z7^Yl#dFW%JJ=59)THgIAywR6$!gZ2*v z9IkHPtl4^-I9moZJQy_DR|uqAw{43GY5VvhxtiPv4x5&fvlnFCeAS+fO?xm587>ol z;3N6^a z#V6S^^zAlaz|@8(=(CuAE@A@WdU)>*RoW*~w7->SlWluXWDx)}K7IGC6Q&A##&6aR z=LGB_g4UGl2rvnGi8i(G-s22*3bQOv%uHkQYWL&zYzNs{%_U{Jp8)SkxO~2|yO(F* zPFr?_%`}F+_cXn14wj6vV;4`YlE!JiqvLIqNWwECuJkiJ&n65({Y4JR#E`B~itM%A zsP4tszMB$O)0v3MQaM@_;MN0_2Or7A`;%rv#^hV*rBx32`|m5qelo1RES|&kZLH^{ z0Sn8m(ki`=Q4>Vi0IJ`+unf6qH+gHqTg7AN+{;s&nilB=q+WgX#iw4vlkUk?YiZup zIb1E()TT#$Iu2oJM_V1|W7%`sb7KlWSCth+^Dv&?>lbx;&4_hHP9Chc$`zSRd>@*) z(kk~spzvlTFH1_onXHBq)1lz#3>_NL>~DhzN@V*DWBkImeSKVfeElhKU_T;z+x`o- zBzl1Rs+dqlnj5xk^w)|?ou7#BR70>_ig%Hkb&j@rm@k!uZ%$d&8w$I^&y1BuOFd5? zz}JqtI-rpWH&xSVcOd^dn*Ym8oqp8priVo?PEJ(!P=rFO*w1C=^_}OJ;DSGnsTY^w z0x2Ore&9RTpTOk#IZUxkl%%-lu|02M=1z}M>buIY z=29b;&HvW(Ze6HNLHC`0@_{2qr3+S$@O;`!oQh;}2#}{Lm7CvQdAC7OJQyoz$g>u!wG@ zfZd;dCvT=jL`}_`Upy9@2l~y%_+I9}-Qm9a9FJOj|6~_o#11eld-dw7OhY|9ivw(# zkYm#qNQ-c0!jnrl9a4iZLKX7n{G~S98z*6*MQJ-6jaHAwx-LV$VFe@H2pglth91ij z#SUuUzKx?$z8NIM&~YKnIa z&mUsw+t!QQ2H(^!UbXJ+i4!M=^@)!BM&JlyDtG?G``aq#JuqX5y^+X=Z5O6ddVkE8 z(>+I@jHuAn)y3QGC3#B7IqX=k0I~geYe1H^L#{fXOANJz^g;JEpQ}N5?+@h?veX@r z&Ko3(TfAx6p;5n4Bjwc0%8Ji$ON78Asp6Jb`i8wbfXQXTbDcPYldC)ZYB^Z z)t_g8lkH-{LXOeDlgVWgc#I}m@&j-^BP)G46LKv~Al(1+Pk*2xoIED607!%-h8p0a zvR9(b$hE8eI+z$~=$n}A{`}y|l?}krEX-oXg)AYUGuXjImpm(-9rU$(IX$~~=fF)M zW5E8!bm(r9(|lfS!a$DA%#^hOyeC+RS-{vKlQzG4_Dqk@0em-*`P~am&vq~%^}U~C z4K;1v){RY%n;60v)2Gp83)K|L(=fQ`FfYRIe;U%{r)9(kEx#9wMkOWpU4qmoJBMo} z8cF6fk(rAfJh_#FR0=1>zP~L}UFqnzE$Mam_=n>8kKMV*-*$iLJy#N-LRhSZ0@2(*SM2yz%3{_>f%`GB{FqtAzE=UdjwR# zJgPV=IBrrWWmwCa)X%pmUggo#SoR>Y!&=!y3qtGTO{%A-92b6%rSL|8hzXI4m-e|{ zEuJ2XqIa=;N$d&9_ifmLi%A4>FK^mp?v63E0+(5kZ9bPjZso5t!8Vwt8gaXdTG`DXm1UN)^?4f@-kS_^{eI3+hA?a{27s5_3DDCL}x=U#4*F`djw6gM>RVQP@+_KFuE5LKvJ~Y!{ORJ-8 zVb?dM4dg0|+YV*YdhhJFPw5!CmTq5Dl)PL!>P5=oUX9e~5Mn$YSW`W$V7}JY=fJw2 zUk(OGR%w;rCn@KqsP|pTBs+BAm@V5@to!BCryQK`5sOenwHPSAP`J2o>Bb`9%Rjm% z8V0Jv`Vz`Ht8*(gh6Vl=IQcqqF2Pn5OeT+0I1`f5EZX{RPMdT0ctqr^^NFoyvf=DV zLD|jBOg!`d;Rpk4khTUcd(!^v)3Yf<_P_KTh**F~I+U`U4{!`{O07{{oSD~qyZN~c z>j2aRe_{ogTxxu!+1E|pOq5nNrpEBGnNdc&(xxEB!9F*l8Pnb8mujl}a$}z{P8D8^ z=sHespSB1hD+I9pis@S%jxIl57i%f4&dNKk^-8kBnV7C3XJq*CRDNc4aOv zf21R)E^Q7*Y~OaekV0dBeCfN=Y4%W$?*l2d3Tj1jO31vM!ozJNzk8vR4i=IO&l<+f zgb5SokT1E;AD|ml(iZRY^GgR1+wu9l%bSoFHU&|ZaUEf!T0bG;2!7tPXZV^3r>c*f zta}&NxPr@z@H7()!OPn+Ii$0fmhKStUiD~vz#>9B4j5yxTi{Tq%Mr6zITaLpR%Y~y z`@ri)NHdxEK%d!U+{H~zEvC*jNoJRm^g3`_*+bj|*?_v;w~KDK>U%+3k%cG~6#4em z^F2H~68auqw#e4@IyGZMJ*iLF$48ASlma-f+UWB^P`4KKT6=~c1I3TtKtTp5 zv1@S1MyMk)5?@ur$vi#xN?qhdS&ZCdxWarbD1Vf=oq(k|Y6rdeuH|7k<&z=x?V<1}B@Y-7_V2QK%0wDi{{C`yY2^5ZCrE3SllC{4H^tX{LG z1tklyHNj&%945TZs;=!pG&niYe;`U{lGkU1LcA?M!2X&w(i_njP;B^6YDq0rNWYvee2G_X8Gm1uw(KQlvY_Gc+MFz0xKueuqb zJ?HbJNs}!2-UY=PD_vYHC?z#VjhbD>D%BaISREmVIQ5MM@aJI5Bm4l?0?DF>LR)^W z;5T6KOx^M;w86Q-h$+>(7A3VV@~C-i^o#d7O>fUR0)^Ubr5QuVe~c|jN4IpS=g`ib z^+1g#(-}b6v7k)!H8bQk8UyUuyER6;JL{6?EYKrOJ&yN_6GY~REyH875@rrJ?f5FC zKMb>=?=KHa(r&YDux4l` z5M}pw_u-740R-#>w&Qs023a$}JdqM@FZeQ5Ktgt(Of$EdCw`W{qzFh)moQLycWjf# zQ*FTJ0lyA%FjX1C-f|N6vBQ7;?eKcxl}EQq8-DwCp27Ev zw6tK;2Gs_FS^tKH`{p!X+m37oCb&3QOH0dVa-IL}`G+O@6ZFiYXHZYlaJ?GgJ zoZYj0-b}RiUUnrbYf8Jwtjm{=-k5p%&yT6!C91W3gOm-I^XJ&t`PIq3!HMZP&1ZUc ze09!ppnZc@dFvlpj;TNOPv`Y)I2C0mDK|%@_rD+Gi&6vc_j8y}VujL=awDV9Hu-$x z!Vr{DO&qyb%EWW#DSPN8@dMe;6o2!&NZ+!vKiX_pNu?IaE?p^onsG&oG3M)vivqsg zt~@o(Rm$|YU46G^xX*g&d9HQ&cxMlOp>ICtG(MPAdIMLVY29v%HhRhT9CsP9+&}sJ zamx>_s8IBZsvCFP7~!5VsD53yXXf4gTE4z9!X)8lRWs23vxs81H}*z*Sg!GuBIwDz zU;NYIpdY`VtF{$WP&|a`qJH(WUPtc-i{6lbw(apU04}kE#>$1tGz*KB2Uw4r9)ua( z&P87okP>Z#n8*O`Iz>G<@E~V8$@tQ(YJ9lW*x)TxLwcn5>uL@$;o5f(uH;8#lOMqH z&QMCD76q3H0})(;yz^E@uZ>AY8Ol9+4AHr$K6|0dh*#%Sx)@vJXEk>FYimX4FBYZD znk*%q5c|Bn1UP0pDCD9MqZx9!$eBBI_i2Z{ISf2CXBH2bLbt4sHi?!#TE3@ zYtyK1Xf+pQ<--cbg|n43`}eO%EQO&MU8I9HA`e2_yA_0+iKX%aUA&x^FBjM#XJp*W zk9uJM9Pj5b>7%!($FJ8z# zpm*;kLC}|f3f!l_e)aJTeOYRQ;!`;lp#bHwD?EXBlEJqk?>)YC{rYCOk76|^ zC1Wa11bFWhj@Un=zLRUW`mKH+=^kfJpPt9e0~aiNkJWtv2JkdQ);KnRM+7{MT#oEkO% z!TtNbv(lEyE^md*pBBu3*<#Xk<^I95x~y6Aqid;3+1#Zz<@@66cQNcd`sDAMktBA@Nfi3*WeFXGp79`Zh*L@>bD5bgK(irWC5zPMfIKsKP zo8vop))DwMttVREH+zJ7$1SGlDy8!5OYa`3-MHQ01vJtzY!?SS7=|}!c#wP4 z%nThApB+8FKJQvKYvxRNrNU|9cKRW&qzjqOOf!JBXyUJr`X+~iYZjJy=T3eFbiK}0 z8DYSncrOG)@ujU9&*jMo3mUU!I0($|JL78&%;AC6h zlz(d-42~<9YbmJJun?I~Ll4G;0h}@H;hD#aw0f5?$6b18DgWZaryL^~5?cjND;xFg zRSV2l?3{-wnA$PtT3r@pbd1@sRGTBs3DAuMwxa;jcHD^|`^Ct3XKO%@Y-$Kz5_@DVk z`d|Ltqx!lnHJ{RCWz)kb%>DfGY7ZC|teiGxOGZ~vi@#o_G+$Vh4?1<}RkG;_i-7f~ zII;5wPN=2YsMk}b)9)%NL+NtRzxf{6h36tLVV%zS_utR{@f!e_J{}LzS^K|%eCUPW zv)>NO?8%cS@XwS4PiG$C^iY@K-p9|MQ_A}Peh2)A`bEta%2*2fy?V94@x=!c0|WF_ z##+fZKq*lE)O{9U8>G=M7}OeAzqYFJBb%YKAKxaITS053>67NgbyhLVZqN}iOaKvJ z*Ow2-MkNCw#fJyB!P%IiJ}f@s%g)c56PcZV=g=sBJkfGMe7N13=heq-nP(o*If;>j zf{I!pi}1t?17~aI3-wg2S9NILUYG*upsA}tpM-hx@ZpShtJV=l*J8yX^MCY~4EJX) zX#N?JZf)5(1KVd3_$UMw(D=HfFkyyEu*+Z=`;F4ZUg&T|iKkB=1&fl|C~fpTRIi+G zrLV<@mJM}&RbQq=sC30-0Np7`a0&r(&jmxxda2ayg2-cPGMCwhb%)OF+Wi4sKC!e! z9{@Zw2QO@iW$=qVAY^c$9s_?9@|PW-Xm-k!QH2p1rtjN;(yYdgQ1 zK&;ycFGCPR8I4fp^-6pMIbuGlDhAoj@HyltQ}h=ma`{!51d|Fg*>fZKCy27h*VqM^ zr5;CPck#Y6w0vm;#94;R!16~#D$#5EjMHej^Q-#rN3gMJ-bB9!-b#3UjD|~x1A;BT z_3O89Vkgflyas{*+}9Uaqlo5JMj7-@2dG0|ynP#!(7CnLHm5MF0XyK2w{`5b#AOwI z6Ob7Yy(kDBDhsRWUF6m8U|{G)kZW}_RDxlA$Pl(QsIT@r&m=)V=Y(~_HcD0mQk!vT z%1)%+@}IsFF5^AyVYHfF68l6YrLa+_78(z$`NNIq5*4jkIc#9+nXHkS1emYj-FM5X zFl+b+OxT%3K=Rcm`#~kTR#T;zc*J{*-1{J6FebHFz_l(ydE>_{9qD4_90tH z?S#uz05v>rY$G$)l7QiX-xTC0!J(yizw#$@qbxEv9(iV*uUqz;Qdy=M%;FkB{YY=~Dy(?G8(;YqP*QJuUuaOCLI z7c$s1xUSwlH}b<%LbB*a$bg%%Jq6>AUtCbWbHgaa8qM0bH>OUqe{w+w1={Z_f}UG{ zr$zI?$>Dxyk2zBc2zyc+8dyhcX_!&-D%J{f$8R{@^1`qiHCt6_v@hTRG?ov9zy+KnpDq$19M+h%S`uAN>iqHAojdZEUm7t zZZmwDFS3#R6q>ZDP1)qWNk z9&{OLAV~nPTbQ8TiB4U{{-cmJUowd!QAos$wN7}!aK4zcD}-d6j*%L{5s2{r@;|cI zA)tcayFM{M$zZBNytAdHjG1xvFDM~YcMlLV_+N*NB$HUYx`>}p@~?B4w)uvd&_+x> zZrlZ`B$#`xlkl}=q(#~nD#gSJ6V#nM$|{Uhw97gmg-mAQS*>_|w+sLD4rmd-E}XQ( zK&ZB)TcPDE#LJWAkSG#ZMt6`<>EISe{A4O5qbNQ}dG*l-es@)=gv*$I4whfCd~~D z{*hlp9X}25Ma6^^XU2b#wb)Sv66+DbUwKUGTZTx($d@obG}tj0cejMfqF1ku$#Wb8 zDZNev^VK!yJfTQg+^jVAt(P3fRAg_7L6!O3(I?FeXC*BkeVgr<3HJ94lvGSuo$G(j z>E%DH_BHi_r<&`X1rMlKm@ls3=3W>SOf}RH{*zEb&n^v=KSn+mYAB_f{JuQA6vNC% zf0+LDjF}+~ZqfVq%X~|~hx33}b29uXw zt|5gzu|HSR?9s!Z*FBcnxVxX@H=te?W^EqZ_hzsdyO*8^6`1CT5wrLo(eT#nMlYvX z{xc!36G5Nz^fR$yoJ;qt0RojZf05?5ckfYP)`Uyx4MEka6MqP@5_PiR$eA-|P9-KT z`gb6OW^w=%_>q+Fj>}_axV*jJ%!{Fm;^07g@5$j;n33>hQ8R79vIew(l?8P-q@^;& z_o;v`6Zv@sll%BzXGv?aplbtZ_B6=A%3&P{q0mKebod4`7)T+{9MS&W3cyF+f$y(yz60WbR+Rzm11l#Ah&-=x-l^^@hiJG9w~$YuX*)Ks;a7JJK7P_`Ht5K0lTLn`gd zeC6xigYUm5o>Lb^h79=ljQ5^IDay8mAxshLP;NQoMx^1A*`QIQV~}}-aUpF7ygkQm zrI%aXm)zaF`DF@DaF17jWIgc}A_mKPM=3NvH~W=nLII_Bk-t`vJE zU=<3_ZHyIV#0_b`d->GYNXC^zpik*CjFp0pXG+O>g*mp^7#it%+FS2m##~IcU7@j( zZG3!3q9HnDgRMUfxHtL}^gF78`1GX0JSG#!vJtwvJD&8Jg>s#t!%>I?Vu8lp5dT^H z51OPhJep`|nA0|!?{^*C!!AFj4G^OaonUh zISK}8+BQs;xilkcHPV#06|%)8d&p4NqrP27jtoLEa`^CJ!w!1IMMbi6&?c^)%F^#t zF;G0VU)VNl8Yc-1ZWsXG0Q*r>bhp2MR|+m@G?$J=FlL)2(> zUc|c~>tqE=-Ja0Ej*!YIzS|S0=>FQE2mxTDmE1?y;LNa;N=*2hdKf^d=)`3?156wb9bWR3@K>e7`-v3n1x!Q2lpjD51StjpePg z#}$0pJ3Hj8$=zjEz86*2bg=%n1dQ6oNnlC^bzyJzcizka;W-6wZ?`sa`Er|(`)O{= zhRktvdMG7%baeD!lVt=Pkh4@C*0Et*bN2iT8`b}qN)6Z>p_FiPh#gEg@paaK%l3@n z;l+0;n>JL|avd@B{cXeVj`s)H|N(8q@}-%$Ca&jD^1{F}_la=vpq+Ds6Fn)=B6(^yGRy|%JH!9%P{M3^IMCS`sE34CKl%X?uf?u zy(}(9A!fI!;{bd**#xUH;&{`eFD4rOZ-3p2RLJ+OJ%`iL^x#)(=QFBUor73kB&0;&u}i&QC||NrC|~a zQH*p3H9=5W=?<8QlW90ks^_OTxn(3@8btx$A7XUq;)lRRqSKhaYlQ3&79+5sL%#;? zToL}Gi1FM40v^T&DOU&bm~#nn_Z>IQR&Hraz7XRTVv5jLD3%S4d+nHL^atOKs3_0X zeEa_W6s|-53s*jbxB@W|-8;>C-TP&R8W4&^(*dLqri#?%88L~xJkDqzn^Ogd$s@gnKy zn}Y!35|C)Tx*z`rLsjU~4<8<0UY8>OK$>r$Qv>OgrnwpC7cr~ z;Szc@xGu68>fb=`2Exa{uM7XO-W-_vinH%p9LC*{Y8dSSWyF*jvqKFUa}t!r4IA!- zLU@f31lmtiV=q(3<;GaG;CgsThV<9-0YAPsl~jr_kj>LOOk? zTz30j8lG?gIY5Bf{^8xaZDdTi*l4bz(Fc%yZ0#l!OWII|+V>o%+U4J&OGN(C@?Pzs zRX}s6RPax^)Fgs~qWHj2tzGQXB&WY;ul=~mbn)W<7A7fF>PF&yd6Z%dhDcLY)vFY$ zk{Nl~k{NkASrN;e{wu9)6;0KF0}(~*Xu11G-V;ZuvMT=SqeKfU-<|*7*cT}$B@WUs zL&SrInH2wPWQcIi7}%^X33L_W6y*xbu7gooiJ6#MI`o2GaH zvpI$Ac=fA-Ms3ESUVlZ12dlun!^mGZ=Dfy7k%qUs2c0 zszmQjb#)gmk9hU`9+e1}1pNqWL;D}>DML$J1Rj5;Me_7yWI`RQTa`PNXA@FTMv7`I zzCKjnRGWUXrCFFXDBnb_it;6#P6XLr?YqFM_u8GZIgD1&B9pC5kS)T&Om`h7M*JOABBudwpn9JO+`Mc8Tc zRt>!Mt#CpWh){CsRlOD}HujSzOh|=HuRaTO9QA}0gt`?s{xd z3HIrj0MBt2TQ{h}K+yZN6Q zsS51*9-7660J{L~p=3w>93)P%5~-__wjNnlX-BO&3aU;*b}wBu=3M&~Nxm=@l=%Rc zv0_9M0J(7-@B;F9c^H(UbX85q=-%yktY+7^^vFNu!@@oO!jPyo8v(_k!5?Zw5wr@u zwB03SO59j2o&WQ>#yrx3)!=jaW`4uRx~1o6crq$Os@HYXG_W`q7iDIpxjkNa`y0LT z{r}-bG=ashAV$M*h(hi_(-R!-bK(bDH;# zs+~MLswcmyHX*|yKSm=q^-nWg->K7X|7XMDdloVKFQ#wHxAAH9!V?i~8l%&R#>U5B zYk{}!r1i9W7)s}S|KyRu-Sw;{PMTB%HAPT%%5pjGLPxPzA%JzFdl(OuRtRqZ7nh=+ zUMJr|I~A^zq47R08kR(9fIFKAg>c!}WWWR+3gw$rec6F^bw*wwtLa&O6&h%l6x4oqSe zI+dw4`0KCy3{U*@>qI>D{4og%5ujAGVh|K#0hSakTeMhVc^$s#VUbpCeMmDND@aq` z#Se$iA>5T645gwzqtjbyxiD!T74h_H_<4mThsyf?3fB#?9b+E$BTCbcgPyOmdqrPk z)76*WK1x2b*Ql$pX?fh(USX1HXTJQgF1avWxoY8yTI*PDq~NgUXS=yYZ%07Ewf8$Z^rsFrHcR90L10zNiVRW*m>AJ*A}DiWio=Iz>LGHXtQ z=cVEWw~iM&AHo>eKyAUMLEP4R&v7J+$Y_nQ2*DC+=upzz^#>0EXn4h_LIG!4RA9u2 zD~}&{pe>ae9dK`(Z_$hN?LSc;Jm=i7tHGa~)vRsXZE6kc4U!UnLHwNnW}Q~8Dvmw-r0a+g7q6~338k3E_#0(@g5m-_E}E$d4)Q#< z+F=&w|BJStX?1NTi6XjzDjw#@*t-}ZTN+NEd^mV{J3c>#nMb_@dsSwyzd0Ku^<_-p z0|5R}&E*%8tN0<%`n^G)d?;$P8N5I7 z_%bW>+>ftc#hSmhPEQf-K|PSsJXH8I03r+yzh$la6&gnG^qlGILX?yW;g>UK@y8Ok z8TfVRce(0cqJ;xO#XwMjtF?DdQqL;ENi*TnrAwlmtd&a}oJ*&hV7Z+|T^4Z9Yx!>8yxA=3 zRl$*h7^_g4b(SD|kwXt!A)+wJV+q>-1b8MB6ZM1DTfN((Qxhfg!qkPBER0tNC+t=TCeC{jnh>9=oR zD2Ml`LQqoCaf(E~P6XgK@q3zvo`^YF>3DWR^}c=k{BR1OmU;u4WkIEC>4ht^sbR|t z<+D}?$ycV|^u=-Lv-=lx0TE)3S0{ompb_SqapQ)G7g7v$v#iTywSFVmqkerI%TK@h z+Tz3IYG$BukN@_f#o4W*qGARd4kZahcXrf@8P*kVoBelXdHT-!!)xYlJM?}(;lZwk zR`|b^v(W;l&ugIX)UCd!*Mz2PYtHX4b7JxNASTM8ztTBGQ$>BB^Qf(IS(Uri^k3-p zLAA$@g?EW}v4)G&)G}YR=(w4oeVXmW(I@y zU#|Q4wXFHpjqQxeif2sP)_L^Wqds-DOb5Q2AJ_fVR3HDsk=qJK`iDgHc^&?GUfeE+ zu&A#gh8lZXb%`CHC=ek#WDpwrRKf1MBh3CkQU!Di8SX6xLR=}Et z<%b7^QU}G~u@f@6(j6C`LTu<)yciDn_QevIDs|GP&6^jyTmbyjD&J5PJZfD^tz4k& zgqL&|)A%ozhSfEbmoK%QsSyU{-48l0mO`8&m-0tC``l?Z<7(vsRt1Dlc8<%WjEVQq zFI8T%dbQp46`5-oVy!K!HofV(OTBSXtapnihMI1&ZSW;uo4~ z57^kWmK{b2Of)+KIdQm`1N#UMT2ulsY&NeA-s-}tNTQ7bR?lxbhr+RLDX|=5J|#>7 zLt72`;xTUA)xV3rkSG++OWp2xEc%8DRRP)SBRN)h6bL<)#Ipz?aOx*g@=ZQ^q$3i6 zdz9jxOY%!74*Nq*dAFKKn&4dIUj@JfpF{x@qMp`UD!(SF0Ga{d-HhC1g&quHW`Z&* z+CK2*D%iu|;K(!Weh?uiRlIxg;%L$E0t(^yfJCl@)AHqW=(HIra5KKHr(C~FEmSM3 zthDso-3ucC*C!YLC<$8g*Nwg7JHUmAQ%@tumsMpl{J;Z z?VSez`tC~O(op=33Ud0j^-=RN09(2a=o)EtrU!&JH~+!zAAYXOJF4H1fx-=DY6`*s znb0nv;JZ+HXSmzt0>JO5E1iQ^-0?_kdp9UDzjP%N+X^1IY#b6?nk6LbncrtjJwP00 z#ayIcf!#oc>6c;4$7_FcIbLI3PJk7h8j&K}g3S|u{(R*cSY!R9UePb@u9TDJt+=sW zaKfQfltK(P1*BHy(4$KmWSAwS{8f z;{3OJa#-$DZw~7+!CC(imIO(RP8(7*Q}Ntmx}Zo1t{UZ%TP|!4uikx!7kek z?9Zw0dY#dyChbDuDiEntceMC=x?7Pe8xuJumRS1E&S}tU3~YFBlHRflAM1kfiSG~P zc0W{1yoU+!s10A~{wXjHV+|u>913Wmx&9rNha5q{s;Eg6EwqKQu8_>XnMzW7?bqc@ zU{lxC{FseZ)lJ%WmB0?}*bI~P2apv6tfT!GZHX8dvKsxyHwUJw9CcyH%e06$c#_vj zdrm$MG4#{C0LL5#8h%BW0Z5eMAMSx}OzBt5#c|8&h`7ffbPvDrDK*t;m$GTNUyd<1 zH+PEqi)RI`NoK(SZTCD))VBd!Ia5Tz3%kXut?bafHTAM)JM8pW^VT=;smhoj9u13w z(m7UYBisk_8SZ{Y;p8op4qn#cA1jB=I$~ecv8L?O?iJDTFr#Eg^n55MO(unhtPs@) zxV%_P@w}8cBG0&oid1k1#$cjxQxN1D&MGTlibeqJ4?F6K=MP86OS}sRr*p|2`kHI# zWu*8i#sBqlqZlOJ6c2!NvZxJ~F7^{SFWlCwd0AfmS1O|cfnFJ{@pKOPUZUpeJu_)H z9ig33Us&c-XN+vXW4v(5v3UP`zCjC0J|-kqb^*T}crhZZ$91&!2iO#}>*jMFzbY=7 z>(W!MgxCf3D(k&v-rdM~y5DM^ZFm~i%*OXbPEto_pUnN2){LNmMqd5`bb;1y+@ZH` z-lMitgJsxt*s!+n1GsD*-ITw^abg?beRcV=H_^4IRN3bIDjy~;*)diFU>tltKO0v% zYQ*EP8ubsJ)EtE)wDf+l)`J*1?k#zgT=f&4GMtUM&bRCan(@z3%h=5MMdP;7$H!;Y z4;Lp9_P~yl?K3uUeW%R~Qw4IS^0RBPYsAuu$A24+b#t&R(&)P|Ear{g8ynTl@%y(; z9G2#{Wu+a8H{ca9`J!odj7RH=nP6Rt#?^}d`jA6rnw`98>w;0rX$-uU!uzjk~ z+T}M%ziorblO}cV(`RyiORXN?2AP?+%E{NaSD*4OO1CI1=Ej7R5%rHS`Uw9ATZC-aaN!GWnwc6vH=QqQb_r-#rXE@A!2ZQ2om015XUvDle( zDhDH)XTZBxpFR!d8u^<|?lg-*BjiQ`qp!=fjEkhLeE|VC`HS%hi*0WoOy|kf_u93q z2?$ts=M&gDHt*1366hMAP*{TxJ(sU~mSeKFNZp<}AtTA!IxVy@CRNf2J`)lW((}c2 zVd@-+vHGb_^TGPJ8(;48Lw>FL-jd3`1eW3|E8DSx=yu)J|GiXNc=rJ5VK=-7DU;-P z1z=b@s3ffaBhYWfM_eKQA$7RiXqo0gAyPp5zRHiro#+T{0T$ErNbM-cD}7ukXlRJ8 z0B@W+b0!q}t#G)&_U16S1FfpKE#5R8FhK*Vg@v*lU%%6oQZfabX0T$^75z zu*)RYK{dQJ8&u^hJpAau5`h_I81Rgg%_nC!T{~$>W4oMV*ohW$7a}I6G+NnG_e?}i5Mme|uub1lMU9&lVi0s?A z{bxXinLAYahFZm9Q>vVPR&Qz$2!^GQ8nH^<$>96Yd z>qa@Rz41+H8Gx7Glm1%MPkI6J{fhn6>l`yXQudwGcm9zBI#3-R3N`o4>n72H1*f8fGpB)9dq|)0(i_FPKQrtvb z_$BSZVL-0>;bqc-uqXg?{PDcF%O4r4$v$6(xmjGnTjKe4_G}60ri`U+Nj{Q2F(YV5 zCZq8b$dDKcQRyR7%t|_E>H8^* z&_~=xEuGNGiMhT^EZ|}_0_?3L2r8^Gw+z!KctGz5LGic#4#FoN6g+aIb6cUe0s*-+ zD31CnhBtI~UVAn6{SGm!jm`V14){9u3X3polzPM=MVNsZhq(Nx>p?hzXoPj!G#E%8 zVC-)w6IDzgIvQ$(0W_$F5WiyhJRu4{5aYn{bgNi}4V!WSuvtT|d(WQGblhM13^8X| zL!*VdMMICl!mVyuke7#SUBLqsV+lWyafJ*21HT|NZYm~BSl>`f6#lqeQG&2S(Xw^x zaNIR#vb4HQ*pM8}>N?u-<)X;())#OaoIvlYH3`E0yZa0Yab6l5=FDMvdf2Z|?JDEpW>}#guk^-oXvhFx!rZ*4I#+`Go ziV~U=1Q8VzKK2_%weo*a5H#LUU}w-BBUuA{vHe2)si4^2@omJyhTQS{xoEz$5Z>)%nJMH(PP~IU8zLg z8t)B5EQ1^+_A*%A!Rz&h5hM#vMMSf4a(F1UGJ_vdO~Y4@3?8FS(k;~oW~8+O?Mcky zZLJynF76{ql5v@Wa#Ge{>iKC}FmWM*9X!?v*Ut?bHna+-SAq`Od&tN5da7n}$DDg4oZ~ONAfQ?y8=gemvY^Tl!w$^8+DYP2WDK+eY_G?Z8Yp$#h zg7j`WXh{4Qsz6i*qYo{~gwQo+hpNH&@tAw0jJa~`*fCV<SV2`&kO2B6*`mAYt4 zaB%QvOfH@)AaZr&{!almY`tr$PthXVRT& zDTGbLZMzC*i=v!9`GT%%HaXh~Rc3?Pv!7mfpG<1vz{=%;;!Z&{ zR&6lQyy14u6L&z-A5d@j(P_;c*jAWM^yt^JvUU;o78l${{=%U9B@7F|oWb9^;GyG5A5_wrx^y#n8pn=)-f=kK^cwSaEYORu0vN=|0ob}AJuvN2H)LHnyYwc{6>#faRjJrWh5Il!re z+@kF4`Bls^I1F`Dfd}AKDQwof8zg#1HhPI~6hHQ7WpGVy&JV^8H*eiq!1(}EgIu}I zch{r8)-y5!2q4$hhGH7n^Q}?ei&u#@H>i^`__4<2Do787iNh1y2eOG+EOmS*58v?i zQ;rUKvbr{pRMa*gWO#%uV5Yn2#PfHhrI8nBCp&kyh%%om$`^VkNa3n#@A=7!XAra( zVJ0F@SVV%xH`)aLBG{K=ng$J2K||5HuoXI~Oh5+4j@_V8(kEh(q6ZI)li8$nZ6Dn z_JR%{cbTcg|1*GiL79TRj&Zw5qZmOF&=?{)xYZUQ_j3yIvM_K6iX&$1i1Lo)IkB#S z7V1%o#~~8JzAPIa^>*{|W9om@1~N`XO&d7b(joLR2^>NiAWSDC+ZpvuKW8}hlr{vW zamsU!gJ2xew$R!zN3PhBU%a$zEWVN15xA0*hn25fUvb7sL@9k6JyNU3Pi?G$lM@xI1qVI(dvQCU+Z*s}gqjO1< z2i$JfQpX8~1sxZEzw^_M=e%vygttbWQb~KZzfi}Sk&6!jL2@!7MCP^BJfZZNg|C?t z)gzFyWNklTN0vQM7VW@5nra9S1aqVJ)P&~zeMnDdnB(kw=-=?=n>U7BYB8jWw7EEp zFOfP&`vVW9*uII7Dd?cZI7#Tdykz^pSTdg2_8{(|HGfXnEiT}%qd)BNODZ2<{ zYD|E8PNyS%254NXwl!(l4=@hahVp{4$c>3~0N&l}Kf(@Oe|UH|Fi?O%e!Of+1$m!{ z@grqR4<{+%=C}hou*lV|1$oU|*L3Na(`v(L3*3 z`zmpkc6Isr6(xUh8?39_`WS#nsts~bC5Y7)QD^pLkgUhA_B83T@#}Dom8l`ID%vOC z-}lj;MPa@-cbyuurRPkij-C4~`q13XM3*Isb?ViNM*BA}efzFmmar@em8W&r!j1Ki zZpmoQye3qer$d|gKR2yt-J(S(DtHSA2ZxUXVmiKa2kirYw$gxZU~$piC1J^f)0YB^ zuOLv2fWzzpacgbQpXb(mIgxSe7Q;WkfPhFIwFTDLgPo?AU!5*LzJGtSuw%z`%|-&s zm{V+-Y1&>sf#0O=Tn1cuTyvZ?{*k{=ZDht7E7(aD5ly)v?Nm|UOU}N&bSU&d_i{As z=EX2(?j_b9W3~%rPX+-rO_USK7&q@;wS;S^VglFJ6m9q2CpA^=4K?1aE`KGGlLa@M z@6)FDvyefOVUh8TIuZP^#n&le{SdU^-{1e{els1%;48}kBr^y;Iu;N+hkSwoCuS0DRyZi`36(OA&~kZ8cK4V2uc)( z=L}U_hA{LvlER{mIuUTx->s(elNoE`W4?!oYpA;AF@T^2Ij>qZ&8yeO>ZFcFRz*6Qy_O^31Z;VHG>Cp1)h36Xgh=F?X1&W&kAk;;wzh76J2C;~(C8$~GoPAC77F8b}J zb4pPB zit!^@F09YZ=3Lw>A9v&8q!eyEU~w~8&D^Q=hh5h2{&m)V)dp^vPfWs9a05u$3WlV= zemt#_X%#Tg`fR)2CzlXck3pGJR#vtPjbclfCP*byt>I6zo?gi?SKE*#=p}!kJL)dX zTPP2{ULW=A$R=SEqVrZJVZfP~y5`QXFT-CGT_3Rkn8@lxS^13lY0bEF%b-FFw+tgUi$~cr+f=s<8$B|*Qh&?=Tt=$gp$DvD}!h8CVpDfdXSrn*68v&!&Jda z+zc+$7~{A3{}J}yaXs&S{QoCp9xIZWm868SNr=!OrIeM7tWL;E6d8$ZB_hdaA+r#Y z6)L32NM>14sVKC5_h&iZ>$<+z^}YT6IJe_C^%?K?`}KM~pO5t%zvjqWc1h}pR<&w@ z+P4v3=Fy|ySnJjMpIfaH5|t44pL9sfW|78ZFqDasU3I|Fr?2x*>#J&#UdV2iiIweT zZ;X>`5bjWj1oQnw4MacpF(L^EC6>)7w;H*xVmEU_^E{W9c&!*BbV@f&Qnxp-QXgd5 zA-AJz76OUVTxHOLRaq5kmMs&yo!<ds;SMQrf%HT;b59iM8@DIr58aW3@v*Wl~1AL)Wn?uJ_@F1KH!>T4y6-LiuV(i zNt6|T+PQDv#G^~#jwqQWwb!$X>KF}d0Ga~e1Xg-W@8)=5w@R_r(@dI8?Ik9A&tAC=cp~UIbgG#0omXQQm5^sn zD{ZR*2wfO2zZQMYPU<4e8QVyCkU-<;ycBAx5|7Z@ZC7Y3w zZJnrR2E-kHoG?3j`mv~v*LhA#zf7&*PSgaz5SW4PTs|490qW>Ro~+hKIBYQ4GDz)c zA0W>=ZE50fk}$LZ4=Hu~r9O*ue2<1Z9rjno(E^4$ufW{`5(VR!-esqC@OPRQNUO&aWp32IoHNocP7^px@!3j z`WOn6-3?ARIy_|e`6gG0VZ%-HEN=B+PTUZbbSV4xL%5+j-P?0^0|4DnJaPtLZ*aAY zAsLCkP$5_qPBaNggjW{{M|MYlYM%S9NN| zZ#5K}hk<3qeambBDq|&?&Iobw5dboiURcc91hlS+GCMgs9SV$QV@J_!?- zq%+IdA>gHpOTRQzV4H_6lretTz;1}%|8~eRcfc^jinyj5-VONS!sCIAJRc<(!)ot? z&PgXmhsA{%y}9IIMX5Ku|NawSGDH>#R6P30!c}&Y=x#;T%m*I4ZMto9tno-f{ArK< zmZuBwLRG7qzohM+KU9hP_8j036!jk#96WOP>CQ^tWNvuWfj7|I$m0_Rm*+PGx4D5( zb6VtvGF9&`idRkv)*FN+!JG8Z}`qZ9C{d}{tkYZC&&hY zCbK9c!Dnbd>JFhj59q%*bXghD>jMhW=;f=YI7Rnp=v43ULP^~C6BHrnNN{kw96KU0 zB=i8wfW+1S$9RLAJKfn%Tt1C6eu&;+#Gq^KUN06@g~DVJQ-F0}fuQ+7!|{;3B?3cs zEhPssJfz-{5kPdOLO+?ANmM1r#59;fIoh{vtGP&hwXkq-8tK2dbl1?ZG{`a!M+P0w zEf&&{49|8^S}|~l*SCPplhm%iiCTWZ4@$ZLEZDzb;bjjv zFfpbpppN^nV~e>SvP-s4iFKe0Rr(2DO;_20vmX%2i%;xQDKX3Di4W!ea63~@O^x$@ zvXjIQPRBcs9{KV^jVbCq!c@nPG~QZu2X0x$kG=OMzClI5HvJb3myB|;Zev*&1>ne$ zI&cJ}AXC%G5Fvc$uoMzb2usAL2;+Z6&47l{9x&k2y~J@%LtF+WCiM>LIeS|*>p646 z&v!R8v|su;)%fxV$|GsWAXWCRA1!SIqc?1su4n6csZs_gQ;v9UL;bWb>Jp1Jynb85 zQoTL>R=f0SPjB za-hTv$j>9+98b-bP4#K(i9aUDUrfR$2^XX3JVv1ivZpmgi2>wI zf<(AIC=RA~JH`Rv0nMhbht=b7Ahg+viCB?q#rdRAAjrZ_7h`&lA9 z8^&e=@bPewJDMPQD&U*}e#Y0(1dzG>=~H;laiUj1xHQQfhBrho7r!`pkT>hW#E!1Z z&kD^<4b*1*Vcz4~cU!zA^tR*Jg_GnsMXTU(uhU68^~v*eikJPMdBz@d6QYC}>$4%$ z2;CO=#%UUTC@}G(pr@x$%~9EGX|7kz6QWvDbrinuBZ!)k;c&EJwInwq^}+rmh96Kp zR-d!o2rhr?df)X-xNi?c1{_;df3i&@>&vf1Td; zal^Ctsbf9{>HN6jGxErz&vQ6y(5b|)sCluSSG2O_X`)ziJZK7|lYwLfb$J-{k`niF zLc`He_mUCi6*>rF1d$knCbpgL-mO~$iX-2J%`ek2YQEO5 z<+`?F8>rLXE%WQNuUiD#IWKS6uwiH!aWn7b_-F=ZD)1^iiTQxJ3P~x3w@zQi2M5=D z;@^yCRi+GzPJq&Ao|z*(i8!d7@=-BIeRM7KEg2@`MWZ}8-f9t7Z~rAD^ytw!can*v zIC}O4ea8Otw5wL7-f1Zmrq_8!?aoYB7CSa23DBog@?bUVf8BsxW4?715%`HZI>Q^Y zk#7f$l4#m0Zx#LRq*iUjQ3lxV$VCQlAHF|uK3XuDqDWm%owv9DVoiEs#2a* z-80bfMcv~^yyKfx)~VA~KPtVOUUN^a_@sc;DqUK^vO$YFxBmi<-X~%&WHj}C>b8~3 zm+v*VKM!Q298MV@fk;Di=s6bw3x2bcu_f*Q-sLHrTGL>RmB+a?kLmiNmeX@u2^}oK zARt}SPoNaopOwaj3H|Tuu1%;@fm@wUFbzPI^zyEC?}} zx;-Q1HiyYL)N;NvKvSqb=lUkSj9sZlF$X?cC(FQgKk<3g)jms30{_vE&4HDn;$s5u zL&{JFxZj7-s<&ki{y@CPJS+kUxoK_!Tf?|-e>py;A6ze_K+5egyAlx%bj+%{7R!vCeoKL zS*z3da}6Q{S7hO?6E0RvqRh(R7k;5#BAb2o94fvEvn~7-bH5z!^=C`Bl!Yd86iO)P zgLKW{T4YyU{%f&j(9D0@+fki=CUkzBca(lJ{7Xh8?o&7J9M70Zxb4kNUT! z_7=PuC6x0E7RSs<8+U2a*qUhGRxvVgp{%;Gy1cM0qPfwOS2WtGO3jQmnmRy7rLXs- zlHk(>Z&|FdUTgbIjf*NYsGSc^ZfH5--(O$TwU^z9HSwA4= zH8i%ncD^wkJ_5DkqCvwQ+dEJ3+feZMWa2n`?R`AVxOZ-fHh$6(FD>2w{FcN1B`iEz zXtmRSNR#cMSE61fh8lP**m$_-%H=!aMqXXQ%WmaeHx^iwk6pbe;q`Q*rWO&)*1k_F z;zIpNc(UAi_f};}iF`Wk`k!n3$!S|3-s@Owr|uY2<>}_tOot7q@?8JNFDP)} z)M?ldAs2$hU8jgI;2|>YHTp=(D7d&yp}%^BST<-sJjJAQM=(QI^G@&$>H9vYM8EYsU^qyfN8aGA~2?qhwon-KNYE8!?*w zk%p_Gnb1D0$od)MXJy=AKlVCUKCWuce##kaR%T$d(c8D`!VK?3GR|$z z3z>8-1P+uP|0T0r_!oo3YbZG7L{=aYJVJ0~w5y`#U(FRVn+oFRzHd1-G&#~p`F3)0 ze2A&vk0OIUO5`Ar#I+?mQeq3iOQ;CeQo`t#f~lJzMUb!s-k5}okNrPVB}e~cuveC7 zsc*<|3{Ms~S8N1zz_X~iO~@%CnTqq&2q_)EN(s_OPMo>L7!2g_pFMjdGCC3m`k~Ue z2I54LS62V0Fq)*5PUohzHgxZ2;ZgJ{WmwXTp+CB=*Xl3ob1;VRTQY`Qfflab5Y{1; zI$WG&4xz2HG))P!XbZ9P90{t>gA^^y7(jGhKWod9Cq&d~^` z&1nLqAXa1K1j8jTHb1~#Clb(S$n`)eKH!2&y;1V}cPbJssrtc&*-5sUtoXkn4EJLf zCjFxYsDv{L{8rM?DFo*cB8wKM{Ku))0;>QO{ZCCHr0)N(qA<{jP)j=4$_7SivC~Yd zkrtiqj}GYre5_7XkXNHlqg1Q6>+Y6dW?!(&HfDJp%T&SdK3{3-{|apD7+?5&EFsRm z$?2T)kNHYXg9(=BTqBK3+6~FbSX!JrMLC?wYX)5q~th>b4zi<3ts`}QLvtg zpWAUTKvc*NN8^~F{HGF}hqmDuuJ2MP@nZ$eb!(axb(3|Sj=u1qG_Ypbc`&bpL`nHG<_Q?;d+&R~4 zRY=&a_47UMM<0yWm`-27A;Ir zH$)j!$M~=q#V6zd!!xb{?JKByfOnL_twQRqh`l=M+~~e&=T|Opb{;)%UUtW)=NcVe zp0#Was%Ey&6ZDn}0Lf~KSbGZ!tq9vwK}7}&bDbZsLv&!S0jf9}+Nh6f>YYWiN>?nI zQuF~*xVz6;MXYu*Qs6s)A*cl&&%f|MREaqr*gNOXpKl#G(dLCMoHCy$+FesaLk5`A zd#bOPe_%|ltj7tsd!imhTls*N-~+0TdDQJ{zR%5jUGwZ7A9*65^v}L;xhWct1fuI6 z!4a4{Y%k4-y0+&w#=lS1Ci>Ss=OEtskS3kz9O+5M)*8_q|RhJ3dJ z!9uh?i28;?z+PNg+>Hs5JvN;qYfdcNGiPeh>4fnU`NjVz(-T2Gz>A_ZS-YAZOcVVOx3?vrezXS zynFvI3)2DJjYk741c9MGr1UkoP-^sG-!;M!3`)M91ElF}kr9_$UCahDfEHCUh#?lV zh)EYtCg|Q%(AQGK9e(=7($wWwfukgHlBB?abrX|4VOt8yO94yi=Cr~FX4yoKw1774aDapZh-$?fgH}jKsq;e3TeyT{@n15i$2oNg`x#<+~>_k$aSWA zbKKXk{qTfc{}eG^J2q`!zx?c|s#?UzF9IM;oJE{75=w_CLP1g;3g*@X4N{QGOudwM z$R}mCD@R!X!Z}K6?sf{E0>Mjx4v|L95_~}tCPdps8KN5tGcxb9GkzTITna;3q}Ua|BW?z+9h)Y0?vuEmUdXLHRWv8 z1*-AhDKDH-9snCM zcrc6B{0{1?)uowj*KgRc@912z0ppc;?yvgWvpB`w`6QJVY6b)|OMr*w)vH(Nsm?|D zP~FV<^ME#Tyq%D+i4Q*a1u7%z&3ZJ_h3=Ur@R8GNowSb?K}iL^`O({K`Pi?QD~H&! z9WY1U1X~SVHrGZ*x*M9hFvQqX9Ed#K!vj8}I>iEg9hC|2w>~HcwVUmnKweaaQ%ZId zp-i&X33MMQX+B8q;=uukwwg{a?T)*9dtgwb!|wlju4q$5`H!tdh{{6d;^{B{_Qoia zi4!u7(!tqzD})ed=5&A}B!BN)*@rz+-S!CxfSqr8#0X z2D^`5I4(f*cA}IMNC-@6rZ+b&Cxk*^X6juTO1gEcq}C|Es$15B!D$^k#<0ntYEnIx zIjQllezH75@$o;+c;#Oi7-UNjPKO4bfqvy*J_pO#!QfRb+of)P(?J^BW4 z$Rjd8rysoY;6a0d126ANTy_&@k7O7`?Zj* ziJ(XOMJ*~eqkgVD3`5NW))IG)KUA1b-d@-&5q0vewXP9cB^Y?j!nf6UWV%PY{|O^W zRAbXr5a2dSDyJe{Ml1-yz)>98q%|E@v*#NL`)pDKL8+-VR;wO_9=sBnNa$ZSKA{uS3qEyuErOQ8u?Dz@-+}R++BPU8?4Y&5Uu8L zP62(KTM9s9vX_&P*)!IH?;02+#5yM*>E&0I2-x&i)t{{y}x>JIYr%^xBMA5 zLE3p{Y#s6vn2Wl=_q+$TR^1G0+~_hONZ}J+tm+YqM9*m&>HCp1*mb)uhLeplfS%H! zE7jfJ(7*GAKzdwFM;Z6zDUd$RYf5Svcv#dGDyo3T@l?a+*%&mRy|k^bU^&Je)M zId=vF@#)UDEVLRsVZD}4L4|jC?Zj~dbuHW?HXbd%mD#~LlJ&Z<)1DWWPOq=V3Kl8< zJULVCF)nu-(rlX<#*OI_45N4mrVmO)NRlrZA6A@h638U+rL(A^!@T;_6FiBDW#h$0 zGVwPUA*}-mHiw{53YV9cLr#GK6+=jPNB{Y4jDFU(*Iw>BdSVa8NlM-Mx;*f!MO57kuWG!g%1&XCNKu z5C#&_aCsJd`!?1zV*2||ac4J{qJ`UAs+Ir7iQZcIw#1GC_|he@!%v)J*S=!)MjwS&CfM#7sVWK;P{GF|7zayuMOVYYE;)YG%T+;1PNaVue*zFZDmG44s2mbLBJo|s|y2nBp z#*htTok>Cld`4%OBJ)J2U%2d67+PrnvNEMi82#Y<>vg4NjXnhH zZ+(>5baVe*PCp# zjP2JQ(D=8?QR}fH%;kDXYkbm4t<5Z*8+STxbKF1S=39kf>9=8A@*DVTEKT)r?ggzb zcM~Nv>8v*pdB}(f)EhD~)}75wwNY$k;j5)kIUvw30Xrzk7Z~P)*C4} zG)vG0uh>~~;jDIf#|i0nK2Dppo>RC)cW?RT!JbCdYyQ;^WjN&kaE=;2=U*h5{iF<$ ztSM@8Bx^D^@f>wBR$c2gx>c2aNPCmhT9!-?QqbeSA3uAjN=u+C4vH;LK%++KG*MHl zbqyof-`3p-b3oTkqq}BcUb|H}(NB?IJbj?AHXhkDN#3J@w<#(+XKNgWNEifwL znw~rtR_A7oW(ThCNmKx1Al`239CYpJ(+ft^C3;|eqma&Fn}(l}KAo)=BNj(cXhyaq zdn=*c9>}n_^a83#@$f*x^V&oSw30C!Eq62aey62}#F#ns5E2p@jMLdTei;0&rj!?3 zp1dskedx04WS=%FD$|z~^{1a!vtPc3ODGA{6bMR)YaXgNh=^#9-RcQ`eVVzf=I-6% zygfFW#yaiE))qZC0DN;2{v_gQ!Wv7dlZ-aj>NI<;^1_cEF%|~-H5PW(yRtn0a8d4a zU?>0O0rMxs5_QEkv5rbU6(A3Z>lhFL1QSX!tqm1TD#KkO1OI5N*g2(`)?C_+83d5d z@+*L*b5jm0Qw2(o#C5FpjV*~hriK|Nfl8qk2Ol6CGvQ3|*^-u)wp+~H7KXppbI`SE;X#;& ziWcGdg~P)tt5`Ccx>}@Y&v2Pmvu@nM3*WLNJHP1b-0w5zg!rr)umoskboNqLS8+b> zcU`))_lkXsA)v`2>hU}e>$uITRaeJ%L%S{K$_R_&K``ZuTwVLF=(NMi_0^!S+1c}~ z!mc}vttcE^G2?sg8)Ol4^WL@T;V@*UUNbaZ)<_NdM!3?~j5xJ@;#K#Ul$BfR*IZY( zetjDmKC{Bn+R~#L>1c`{=oDJ&c3(cxb;67;Cv_QV|L71DSDNU3dPz<^YSu185cdon z9iVS44%WSU=Y01$N*Rc6vE8Y|+H3yTK6`YWX+)~#J%DQcrfTnk0M=x(gYZE#&t&$_ z`Qm3a)6sDneFEw!B#)AC&CoA;xcf->Cm?FJ^Z;NLE*!Dzn+MMy(RCq=8TYjuXlGv3 z>vyCGEX0k#A|gew4w8@FT}YH02~s6)0;HUi)EhTmUawZ#~&BB>PCXU$UV0jW?xJqE=!YS4v3G0QEBbB_( z2M@gTEo0Xe5B;8ocmhzeBZ-Wx7PIu2|(~rJrEkzR9E&9YQsHsD=>F?$N&%P|yO{|G{pO7MU~Ql^En%CX4sHX) zj1KxF!?X19!#J-3aV$mu{(%lD7~u*MuoQr7lptYcg;Uf;{eY61kU0)OFACqq;Qji0 zlCYTZi^LxLu^AT97)Yv;xXP%4l639ctJmWBAp?1s*{ZP7`$r%&MzHtzLCret)w^>M zaPdy8{ODnc!CT_vXE3c9B{&9FCPsct?mMxq>{+B>nJS0#Nt~z|Q2QurVU&&RHbe?P zov^20c3-}HIYo#9nL9G#1;a@$-deu$`=>(+CR3bINdhvPa2(HWknj`fxQpimB$5W; zl%#l{n|l%gXT<$eQ!W?1YU9y1t58Qf^=8Y}6hn!(Z;!Z-s`=34?&{rle=eTs=)=T; zs~(fE8(Y&X*e=m}r`PVFO`!%ghOKg)ImEtJlR+sdzxnPuL*j4U+N*J0`3rqti0+Hi z)7Djc%!w4CtD{|~=40f3)>T70_(*d%%`q|ct?~NOQZtFN3ej49lhL=_6Mh0?o@yB6ILd9ScI)XkoKdzgo14$-}ao+FB{a^ zQtxQqec#Cqbk*ywT)C1{_5sLXKN;LD1HTbe2#5u=6=0KZhr7C?-&!CFgWZq$uCe+b#> z6=V~Dnl7B@wYE*#ct@tJ8GE-||9tH3H@_76g91%zTlU#iW3#td_LSeC3aeSZV&W3W z!p&XVV*f)}A$~Yv4arJ-w$eNA19P-+A@o^5m=2B!PLYPGH58Co3b>irgiFZd=Q^5B zI_XJl2AZ=G?}I#wCMbMYGKsRXlzKmGmqY$T$xxwA0|ZwHzpCJ)_U>}rZ#wuR0bG7? zmb9G1`1WLl&5tO0Ps;wPHLpY7{LsNms5im(o4QrKdYi5G=+K$ZvN{>u2E%c~=FwGe zaac>f(QN{%*~AxNDFKClz%kLH*PKS!BlWuQSXv5#YJch@+Kbjqrlh2hj7ZxdS-0!% zN@xG^U8;O)-Z2(OM3O4{nG+^4YkS61WUjsz{^yGr@6@m}u&%&sqL7{X{zp>eilu6-oSdz@fdbY@ZT*HRj zz0)<7jWYX zh}7B>(|QQOHAI%YjV*rl$UhcsDris9nsklIPqJPsXw2@nG1&tSj8VVYP5s!FD+aJ? z5tc_bq;$Ft8G;`Q@yd_7TN?al5j4?is{bM$S!#?&1X8fpZc|?ij7A4!Y}obqmAfBp ztu|K}GYfPs)%^chR z`3bik{#B2l(Z)L)G_D&NOlS5fGDKy}^*#-ZrIq0SY-2CDHN(g-?r?{MpG~A)9v9Pk zqMujm*FGIR76fIP{~u*W<%?AQ7SBYhT~+AZ##+m;N8$BIqQTG}&=iD|1FUj!y}NpV zxrZ!4N#&x7*@7LK-50I6^(X`I==NQ^{^f}>4LEm8D6L*TOkOp{K$;^j+H(FNQ_v|M z8OK$Ab;eln@(%}#T8_^57yWu}+)$&9i#nT}ZgHt(PmH<#?pfN&XFBqQ6cmLx+ss6S zPkZ0Le}9BwXP93PN3OSaiUGNl8;(!tZ1Zy0h3DWEW*+&Y^{YR201kz-Ej4BnIph zehqadoG4<>rw_sp4Tjt^A;jU#fjoJS5la9V`ho>CX#Ww&nI zz$KbTzb9u?_=?V5yKVssH5?l!Hf(sve0n84z)DK8I}%lBIQ9TQ@(i04rK($AxP+uZ zZ~)2tPbmO47FD!RknGB-PY%#=VGj4RLi(|o6i&%oVOGvG{k*)q?Lfz@#Mz)~sBJ_5 z4(cmF2{Ovggyzx@oFQC5l%g!n5ePdt0pGK36_`v(a2v{ZLwSRYpTPh7JP-}8p$SX| z)p$mpJePC&PUq3Yi37@NCh2zVI_LS>kUj^iM#)f*J@Ti#+rhE*YIgT}?GyL^pQn@b zvwYmTgT}Vuf6hWuk?xqFTu6Gm4q|)qIfZH!_**0+JP1m}Zp`4KD@2!0DKd^O9Tz>V z)~!d6#+j}CL1M~aP*UQ5Ho=A|5EpSfs)2(TmVF-wFyp;@_vg5~;tB$6(oD+9$>H%! z`#=p<*OQ2b^CuuQSXGvrM*ZQQayMfSmLQ@Dt3KRoAq_tsC6cyHJsLCDzNCHISZt5+9^E5lW` z`Q^wpYm=^F2b8q`H3MgR$6mRT8xz^+UCIuPDiK%49@?YR_yQpL7 zW#wBu__GI=Sdkb4i`blGNxp1)0i5AHldlvoV=&c8L>voDbC0r`tL81hsrIYD zHUAqJfnk(ka&mHK%we~F@3vwPE)TlR+-}~WgMFp0f!Do_`jQGb6;fOfSeWFt{R}Pp zC%kSrt%3HVe!G(n8Be&IAK5Rp_=CxV8Wr_%SRgB}EQIAD;)4VZbUpd_#p)kvw(pxI zgRxPsERRXEZ7fvu#*JEq%fz2cYqY#}sUXAjGFpjbF^D*_EnEd5nvcKot1LfSOgv* znt|-9XFxuv)Ty)7WEQgwq`Bx;sL9|krFL3c8`;&)5&B4Y^>Ef8?eNJr{#CpGVhxjT zuP0N9D>WzLl!sb>qV417(NOjhxdHzwAutLQbxay;h17uo$)l4@cu<&c{F536T$|l_LjrO0%_gmr?aB z=H7YdJ(o+e^!RMzSwbCA`x?Th&#&VKqh_GX*h={#-t0FI-Y0Whg+aTbWh^AuY477n zkMl3%d0;QACMo_SiZh!%-RA9#ct<=SuCLs@krTeby+m2>LU<6eydyNIQqN-KUIg_m z8I{|&-=Q~v4tF6mit}IH8&!;6^S{jZ z_1eUtE_QKXQREyfjmn_tm#*?z*-99y6vTU-rP77>wlJ*2YF_S_?h6P9- zkmh?j-rH2;A_oIpcK{m@BkDV%St=7J0o|q(H>Hp+j;?`FfZKoyP|5W2>rmPY9~}7r zb(!CfIT+UIlmhYUduWJ6ej)t;SgueIrd>Fa zo?mh6N!2${s-Rbuvyd7I+AN8YVki_S0kpzAd#Q_y-hfpKj->REZy2g2(6Cd{%_HQP zgv8U$_LD|%aBqkNV^M zeJEwsV6qw0Ha6~P&4P(qN)=}fB+~bJvR{{RmHj>*_G*ts2)^6jKU97ee%w4Ud0%ho z`giZy6Xs_n!F}3P@k|~L4X*Mrrfs0Sv?{oar z(Vr4W0YGAwQ4W|~cPs}Q3?q!p$@s+=IHiwq$9C`AcZ{qL)nHKSwxLxL zzE-SaP(|6`s@ekwPC8)VW`!cnjD7Yvgb4W^*e)l(YqWjCKgc5(g?{vCzrp>ls*e2q z${-=&%^kbB4^HwWAA&kLU!|Z>AVIE95f~YHoS~0YM%|0_(?Du_t}b`Sd9alR10tPT zV^EEOOS6wg4g}ZWu&k2YfVzo3M)K(1zc)rV6ji1c_RaBXe41_gPoEd%0-9nO;8d*s zCNp!~-v$U#k7CRKG}MQzKe7~kFhe@4DcIg}c4gz^dGg6l#wNx;S?%gUE3X7c=k!DM z={6to(FBF&W?*v_|8Bm->r9(=o$C`Y(6t+yA;HKL;NLcORm=T`yNOC^b4J4>SRTX_ zo ztq6>uE>liU83>vx5z{>Kw-OV5(B$f)za`UX1kV6fn^?J4&OB2^48=7xS=)9-{DCRw zPM?-gadxp(vT|e`uMEVx2F3S@k&Kie*AA3eQz^%w&}ES6A&80i-0ony6u4ll;-IN?e@9q2KdY0rTTuWFm1q!BqeYg~NeSWctw zF7n#`y6pRxBdJL7eT%atp_XVa8I6MtAGo;2!)@_65HAuLwzGIwl_$coJP?aacVf zGn`fB4Wh;cjGOJzDgG%Ot8Bg)p>4iOprl=rt>9QNP*NWc2((GZe^btdUng;Y4(50_|G>-t&M*@$+5-d?fVnI zuN>wVWMf>b-8~W*V$Hivh@5lKy`YZ8pdZ%8-cmr~d+q%lt!udq z2HFW9r9c0_Nv(u+XUaDK1Zodh@7=9?_fyY`8~?HG40q9}b8@}U${UMZ0HNhs1i_Oo zea4Jo*4B@Q`Q)Z_$vAmAmQoj3A!()?6fT{}%7ZR0>}&VIxD$1scss)AVAj6!`2GEm zDOESwx~a)pokKv;fI**l_97A)q)0g6s6~qkhHd+ra_QhQnlTql09?z@DoI^Ja(~&s zN^}78!~1^dzg`KcMH^4l2!7fva$j8Nu3+2Yp;Gr`#SlBNl}CgPBqb4>p&z}XFch3q zXji(P72()EDqw~k+@QqdZoZR5vFtQ6ohB#+B%^{b*4}u)+9N+e`ja$M-2s>Zq_`=I zPD)FtKAKCJEQ<fK3k@`j973f`gy!5$uvp%4h(EfPj`=1)1M4K4yM^)lESjk z@NH||f4WsNMa1W-`dD6#>el%sb(hTIMJM-`z|oM^73G>Q@|gC@H$K2V%U3aCACyLB z;m5N%)TM7fe30S56v7<|QSn66=Nu6A>e{Q4Mci>2eKVP2t*#sn?-@=bqbylLKX}=2 zir|q-+B!OBFE6?bQ<}#%mQ5#ij6EWe25#nSsiQn6URi!7J$B^$v44sgoePLd zgpQ#OfyJJNE$9x?$dNm^APINBhdeqmCV-k-3JahH_fE(Y8p&# z(;-Tn-4Nvr+j^LNnaEzDz&*1cg>9EVfLcCDA4tY?Z&WDcUrFS$4N(7MAo?_pYZ)s9 z@{7{SUMZW{2209dE2MJ7DEpSDUvxpegedqBokO@J_yUSim_^#1G2#a#ZcKbD!r4gk zo)+s?IP0INFyJfmY}i1bmijYCMI@<3=?oq`wfBNolNn+&!E3{YV=$*$LppWp6hWab z0l}-vf6b0YPmNPO4W!-bYr*A&Jf(lN^^j4mO)55xG`_vhO@FfncI+a}I&U)vfFLAi z^+T?$J!DGk3LCR(c#+Z1N%-}U1A|tM*PVQEtfZWkmbzoXffpR-d1+PIB})&&NPC!W z#xV>>oX0B-E-mbG1zwqmrnXf%}_AEbN z2Gmk_EY-^~2nuE8|rT=$0G)q^NW#mf(*$ri!b!CPTjgjVUL*KT$|d5BXHsb!nGBUcFpo)!BtI4VxX|0#sUoV z(j9ut@p$v;(|zXbrG?h%R?ehct$>+jt8j=F7Iw1~*D03HNe<=mqQWSsFHM5#)yzgL35 zQ7fulz7n4Q$DbL))AZA&P)1~SYDLGb6~f%>?fws6Zsyu2=o8f^nA(aJ1GrJ3H*nSM zWtLhZ<3=Pv-PzE0fq5fRw*u_h>}4pWU_r{rwsT9iZQAsf`E_0OUajmBctzrI zsdIc+V3jaEAxe?Ss0Ph~c3a8ULyY5qA@jRm4$|@IUt$pa6%|sidJe3!oUW2qPj8|W zDk@EyAh(lhgEb(@KcF{0k#Q&99|#Qe99XQZ_MOb_e*8ZiycCo*s%RSB{ zRgr2x2kyjstG&F3_1mlq8p^Y4`0mjZ zask-M9W|dgCMd6aP$EpPlppa6oW$Q)GRzJVgAvrqEEEvTxRC(@SYAg_;cQ}}Eis+c z@2Lo0Bya^|_L(1hqOU-aD%gJU3JDRDNI9u5snZScNaF!Xq_AXEoxb*$FJH_knR(#r zvo(eB1;t13Uu9?CV{r@hJ&Gw>GXYQHNmB)+L92C}oRQ7WzGK3A&U?!9ZJvnjX$MP6 zrbpoyiZXMncfPyHPWr=S0_ia|Y{NPZKIjgT0GfZ$fpgfkbTVQq17NJ5T zkMSL5%BWH)h9^J*5wuAbKSmT#HEp^9QT}IrE$)G0BVwa^J#uA)_nH_kZ zzKs>4hfMSU9b_;Y7ECD}J#LhwIWO4e^6|74u!a|7*kYHN{aty8y}deF0W3+OznjkH zt&nZ?`E7Ja!%_DjF#wFyW*z8f-{f?$TrZv{eIwhfANB8xnX6Oee*l#djH!w(gYdBk&hFaX835_y4j&p z{PC@0JCoDw9{<-*`reqm?tRzO%bWi5HMA$G1n%EYc$o2~ya3(qaFt{q5B^?e@Hf~J zvo`k|4FBpfGxy*~OTB-vdr_P;4Xp2f?%F%c9U_$q8#Y+83XxU>v!lUnzCHAn2X{Z) z1Ps(r3UIo$5qaqzJASKs-6*quMn6B7^|$i{@~oVoJx0t+t*xfEXVE50fqLWjV?JZ; zFasv~@UX^4)>gY}4Ax|4yp39_?eA6M!-sY0-#^CciEH=bM;5?pGq4DC@`pMN2>8|R zP^D9*smvXr)FYqR-PpUs`tYONx4$aYM0o85k!IAKk|zf90D63>wS`^fNm4KyK8(jt z8)DT6ejK4AqKf}O z*z<#asH(jNw2=yaFC-Yxva)2Y%ggbof8)7Mg=39;1vrD5ahxE`Tnao5#zo_%VSNFi zZVL26?{X8_mO{+oOgXCmuS!2MR%k4fK?rcEn(J}G(}5#c3G{D=++p7y`xSL?XAlN_ zlNcn-bhca0Z{NJR5)z&mwUOlm)E-pIewU``lvd5VfdH5flq zw;~!t;cm__v^aF-Tt<`HLrXS65 zVg$zjs;H?y0Trz(I|3=rW!eRAt;ti%cBUH4H99I@1C*ALlo-}y#%$YHRY7kAZhSgj z>JlnbYflN$6|2qp3bZtmItqV(SmwY`-B(uiR;Isx{tU;+e_VPNdMa(Hg`a5oGd@ad zh?LWpRJBLr) zD=XB}-tf;R@u}jOv7PBZT7Wj|-FE)r!`N(wIQ|^=Av5y`!f$=GbTA%E?L{TJFvfMwv zOTOXNvpFE+p8#zsn|uR(jb0=}>arOnaJAV2@J1UFw9a?a(i+918}NPHG-Z>8AdG*q zu#~cSd^E|r_9&s8mZCjJH&EiPCY!C;Z6(u81bP;C2bYT0E0T~cw9;Ml>JYbmkWND? zaE=z~gnCm{r-_am>*pVMoT_y9sZ*y0xD_0wC$uH0#+o`((>Ye{KM#kS6%B5<|HIgI z^Im1nX=_o!p%%cgqF{8O3GP@I4j;GR^`K5@<`vh-x`>L3vdTFwRebt+ei+rpf0giK zr%&k=k7$r%v<3>erYutDDPqMxm<(IOoZ4l-#^R48^e}GrKy)RW=-?F~Lp5_JPj_dP z_tgzrTht5|qraFgoUcOuF;wLnMU)lQB+FAl8jY@A5ci3Eet&|ks{3_yN|+ALG3d$fHDj;q4S_Y z2k6Q+G*LNE zy<7HQbElENFKQCRWEf@-dK9&Qwem^040dVj{}VxPyhKZ~gkvaV@Cl?m`Ja__Ez{gE z^y62{iY9T1>@F^B52bVURL_Y2Ssu>?S^)>euPW0`C?L&F%!YIYl0FMo%L~Zt6&PN3 z(ohBV^sL{i&qKspqQS-5O#>#=VEiIXj%IAdFn* z<&ubv_zbh~C{kh?%IFW|OcI`z;kI<`@#8v($v8|G=A`#V7PK;X6()j@jLnuH7`Bun zNoVrLyvm!u;O)=f#d#Lsp&X%9ue+EChZ9R?nel$8d7IMb>3+U&{(QHyuK?EY_ugme z3Y+o&!l-LHp!T{K*x#43SF|($G;X;uAAPnmK~`i^aUF5z?Y?w+%*Yl#d-nUJFCbX> zXWoUYbYt(bvX&$#Ej=|k#)u~sp+Q}aS=f!YU%yTc_4ud$JvSL;5a0~qVuZ@r9{X+D zL?)retSTD-JVq>VGsA zM&YxVNotjHNR=sEYHUanXu;tth^s6(NUag?>+X63iI+2U%JyCVChv$S&1;uvv~5BB z&Z~Vbc=DSv3NbYJY0 z^z>Qmvzkt>4FgARJNaox)siz4b>h7s$LMUkO9qZ-4f<;Dn$&*kjGVV7Pr8p>xMIfo z6!+-o2Y0k7uQ&I#yI10{vtg0>yfw} z@MJ&wd+Pq=(iIKViOWaM^n8 z*xw7CO2!AZe%+{`Fh;eY_k?NQV}H3lGyJl7)x*IlhdR1^ux_31sxfFu!>kYQ9!3vr za6r4F`m4%MuiZ0-~YZTn}RF;wx2TaF)Z(0`hKpV97Hvd0Ake5zI6#C!gr(|GeDGg$=0q<^1-yregdt+B+z$@saR8PPtPb-Rr+PGV1iTv$O7Z_*nRE z`k9j-4@I6mfpovLqU2+I`pYJei)Ej`e!aVCOS@I~UTBoZHH`7d_B-EgaHkf>C!S2d zGHlQMXUqF`=~GndH}h|UY^TEUHLGVYE1IfjbGeD{gI8}KRO^q1YxxkF20_z3nOJ#x zp?84v_d$6EKlTvke3ia7^4|Z}*S6@iSEgLSJ$`+8S#34(N4<}}Iq|jcYxfyZrCgcb z6Q{Q8*RMHvB{fKtBdsW}w+8A1^smM>Ir344iWCnEzhX=4{=2}Ope{FA`EYDDArV;W z8?S4?JJDs$z7C`mq8JT8Kf0J8=4=Gv5@j+l@5c^CegpH zFiiaP$thvCa?WmR+mUtmV8)$sGxGIYmtLOtrR#Cq&fPzMnCiItS3sbd+UCflvm4f2 z*}rr?@zdYzmtZ>dYT$^()Xy#qnG0q zLzn98}I7MUX&Pq*!}OPyyaZWWP18;RhTFY>Lbvy$>GCi7V;x?ok3fzqIst z%F0;`*@%~Mcg*7BO*tQx9-f*ym~JhR1Fh}FG9!cBtm}5OOl@yH?}DWu=IP19=k&{$ z&a#Zo9(3WH$Adlhst;aN^0md^EqiMgzEL_c@2Qg07nKW1n>QO5uUG$a>Bn6QvrdH% zl}<-p85fpUIJ2zvhAD+=W1l}is(k8D_R%g`VMl`(EpFF6xnIrKvu18+bE7C`mfiT{ zW1e*PKJ&xb{PmoP!=~*SAT%`MndipRuP!qj1Ek4fkk); z7k2}1?z7mHeJg%HjgyE{H{ zuDFdSYOaHfD3n+ndqh_qGRORzZrNOAk|$)O3cg&(C*l2Q`r+(+(P=L#FLjH|pif1p zdWaNOkjMfa5lNA7E(0PJAth(|9Rw`>7nfgB`3!Z1y4JzwQ{FgsA6Qxia}hStwWLz5 z=2TpwNEb|$H~Iyd2Obxv{(H{s+1`8hsDWY&@?LDX*J$H(6P3R=)LlJED{)NNBa^n} zQ%YaE4!zK4L9Yom@88?orA4^fx@C6Xe&UOpLyqM^zmS7#yp)MtG?@2ws^jKgCljtN zouuFJYv=OVfqO!p$3FBqaq#Bd+GPz^#x0xKrvJVBEyi8DQSI`RRd$9`>K!=HMp4Jt z@S4lFhek_(?NnX1aevRe(s7RYGi|<>rTage^{bkB?fh>@31x@?SmOxDc11te+}1VM zDS6V>3VaJz!aS4?1_rGWC{uUF6Pu#AM)J{?+yw_P$x)z-a9+x{fPhVK%>Fe<&2X+j zaByOBj7m~P$#gvo0W7dL1gx`yO@WKH>`JT#Q`xm()hxh1PPx(kOz5iFQ2ib^L_!|X z#)uUE%jK&zrcj|FN37*=%~MG-yhvD_V{#nXKQ*%k+yI+>Cc&=G3^ABsFlg(+>SwU@ zMNU2uVm%l^7PUWc05g@?zO?c3qA@1p-c zr^68!9ru0k_xEu)8WFQIeDAyQ^K$(*Zakq<(qY}Z(>FgB*NTgoI z)$7bvH+0_!ek-=Ky~XaqC5P$sHV*GVT;ZF@3yFr?V0G4GP7aWK5e8= z8t*YoiLS^&5;HLoaD01ngWj;?*8KtdIe_QrG(j~Sy&WL|06Ur%4P)FJ)3!tq&P=Qp zbVWBgMmm1=R;yK%O~Mkd(fMnWU-y;!OI%;fB4x^KK@b4}q4Tu5Eaj0v+o%PJQNS-y*m7LKze#bt2d_Y&oqmg6n)bE*I$aU zjnr$tZ1CjR$(l2k8lig3c==LK6!1(sVLI~-g~g(RW@D#JnF7^w_~OOp>FMcA{!>c@ z+Wd=DlUqFg3WZff(=HW*KNz_YNfaDnQ{JODk#JN_#T$%MuyXRV3e!DU1 zmzS3p7p;5oI0(2lB!A3!d&BD|EX(@w&cRE9yV8T12li`BJJ`%nZawSR(%QNPeh-Pj zW{o~fNx9A=K+D+wFyUt>ff$HUEy?XqQI!n$Iww zv1w$CQisMf!^SM^anG(kPL)O=Pd5N~9A?g3k4|Jd`-pHBUcCzZ9f%O)R8~-0dhguX zSbcD}Hgn^+u7U-bo0}srR3b+NTT7iILyNyYZ-Nd)AdKUK?uMN_*$qr)9lWD(hjo*P z2C3b)?Lqy6DBmK?4G}{dJuh%xxvEukRMf(<-%D{(UBfvz?ImuycB}x{k9dxhx9{J3 zA#j^Uar5S3)I6BZn^wEV(l@fOXt-j<3ey*cOBqY>7ld*tpSAaj zQ)j5BJ~D^a01ADug^VT(URgvEJ#9k;}G zaCZK*G}`<6#boO#O+tr0{#>z6d)=F3TH4wInc-%VfN0L@!<;*H*G3M3|gG(uS0<(&C}2QPnbD2|==j%R*cllX`(5B2oC-X2>pHE6G1{Uf{l-@Nje zYUZ}(OzOwE$$|aXvF$-3){^8csr+ng&2l6)Wrt}9j_FgDNv^1nFs__iRNdjW-47SD zg}M*rVrQ=~C>U05{3<$bTE8EQZEU^tLRL-W=fi{5R!-3uGt+ne4< z>CM1RTWq}7+_C<&EbFOPkK4^>oXGyEYQm57YF6tS|7w1`TZ6SNX2_prY)Na?x<=2? zZWsIZs``slZE9Vw`agQNv+MuY&kgV3`MT#FeoycAGpG2WJ^sAPnHB5SImpY&YyPPD z?=R8D#@16$^G@EV>09)Qese6?*sjsL{kYnnpIO>E?c5qQ;|`XwFJ|4gOLK9Z^B*r0 zQ7^at{XcJaXK0V(g;79q*jV?h`ZYV}CYHU`_l`{~RNYrT z**o-UT(>z4Dc})&$joY(`Cu%7ckkaf=D8#uz-G!I#gOu{m3K=DRsI@$FhaJqC8dMz z_F6OGKv=f5+UQ#)+tZpEKJC@yLXC4PrXfMq>e`k4y{4jF$Bxz6tn7&N@Np^{++pL8 zjJEqKujrYlK9klut>LXt&cP;xSZDp*L4yW)&9%|F*w!a-aQADU3MU*pS$Br%o!9Hk zn}k1dJ2qx%%J3@{cFu1XkM8MW*5i0zXqDjO$LlFLW4-q5`Tyv86SyAt_TTqT8Okz5 znJEcPhB7BfLK4!9L?z=gMTjC1O{f%^3q_JdWN4;PXdtsfB?+ZWDLU`3wfEWk>~qfR z_55G|^{j{b{qFlaT-Rs14g@T}_209NTk*1!L)+o0f8703M%cfavrQ&aRYwWfCgXkE zmGX<+J8bQsH$8GjWvqVjq|RUdxLo$lA94TIpv-fQ;BCg-E?1RVJp8Q0O=eSyl^2{F z2~gdkLmvY%$<}(F@_!F8f?>1o=S2E{>*{ZE_PlZG!^Z{Eyxsjr_fWJs={fw9gUh$= zTIsDD8qck?dgl>6qdB2CcJLv;A1ZN!JkKv3z~@kY+jdTU?Ov~(+}ov#-8*lsnq5pO<4|2fc`JJop{k*FCE&9V^pN8va4u^UDTU_NZ>-6;{0jQFV zr%Y*0BVf#10iWAOZ_m-BhK#GY*u`CGe%vAdx&N*9h@81;o@2PQU}R+^x&tE?0joY<{v9G44Ja2gk4&}3Pc<+5?&lbOm)QO?-l&wSW zM_l}J`RspN(mvH4FAxjd{J3H2^Xfx~4rM)hWF0Yb=uqN!uj$1N6oN$)HAOfyJEucp z0EJpe8#K{p*LVzB$&^GrWFQji@V;9a+`x(Y*ITx1sqhd?+ZbS)0We*?VEQHD@U{Kf z`v$sn$@}o(xx4c=ubC@GpQ4NX$|W`5>sxqm&aGRga$I#|%mJ$linM-vXm|3zKzfSu z6F=RUJ=9Ah_V3%bo#R;?-f#y6Po7Lcq{p38SL9w_UoVC=f8MLlCCyXt6)nCuh=CNH z|3|1pi<$tEPdwVMz$i&Q_fGyM5qJ-Za)TjMZ^9ph9~#q8bS4Clj_Mz2w^3)8f)B{wi4ipgAqbPhrr53Q>X_2B!1L;7{ z*&aibbemUKi+dqTIO4BVaMx$Ccv?yJ*W98z+TS}mHu+w=j6-2}BQEj_I*3Xl>)V}f zE(&LQoIU8U)Y|6!#U;+a|dt?C6$C?gM?<6nuMaVS$ z{qCTCk%B49kd|qdCz2&D##cm)LZB&XY(+&RgokYt9H+Ce7vgBeCpmx{90N-~UcQ6a%P>Ow~dP$f(pHD8|nZ7CV;bw2-7&VIhFQ+JS*4UGGITV*=>W zy{52=n`rWy8YX_)~&?$@gKGe~2-Uz;C`SzP- z);WKK?f5fwFVCI($UE#T9WwB^ICQ2?mwom+10?kj(=+&a2l6~9kj^3QgLFA5DFOiGG|;uoC8 zPmqG)^@wKj_4A{&=gV4e9;>BQZ==zeVtKlz;7Q_&rq~xMF+EahMs#kSdD*CQ_55Oe z6@<@{1#41KQMqeZE3&3)HMO)(gobt^$^A4`uO(v&JQ&&{g_=dL!+qSs2r%L#l!UTZ>aUL8QJV%l1CTCq&*^fUdr5>chinHr+=jHUM!Sy?I6 z%`MEf--Q!eR-xHpVqlD#6)ZcHq!ZZjTPfN z5~t$t_a6Av*h{uWi?gqcPxx2%h*KG^+h)I6bXE!lc8kc4Uu{RUIj?gZ{_xF!l0aeh zlr)$O8_|`N7KyUQDJumCrA=va@qMd4!H#GH`p$FTzQ8rCLF9-I@d|{w*rk zW!Se9LxW&lVZnFB#%hX&nfZN^XnSNNux?3&&1jxGeC*htq9%sPDt7CpVLm@~lQO>1 zpNNF=PKBqRHPPuJtI>O1wFflZPmTfKD*h7Kfegg;4o;I=vzDaknpG!($cv-vr7JMB zk&%(4qodQ2^gF;=z<5WE8V}?L6n8sJ)FxoXtMeC&>bkom9QXH^4+;v}u@q>6 z**G>;o8$BwunEdY=;?-%;o$3zTv|qA=m&FZWWOKrt7vI!u!tPQTrE0bJnY~+t(HK=}L~)#I-g4IEKgSHc0^lDd@2IH0 z5}uPuZ7gnPWz}MkwYg!y;U^iPB{=9x*B^fV1@c6Cw>A&S9eIz7m6%q=?%n-)YfF|d zw`-j8xgG_Kn079NnM9q6-0SEUTM1h3`*TrHYzJA{?Q<9_U3NRG6fKBC9>-7%sQ~fi zJDy7B&6~22vpGQi1z3a-Ib__uJN0Uz?JI+J?b`X;<)&!;@81M5o69XfMf-~jZmy8SV ziRT%GP7s>Vwh7aFplRD(XPv!XbU0_TlAUJn=4ZD-N1eKp&jYq9-lE)D`*Ca}=3E=#n%% zkwp$U*RNSupNJFb%(_Nx+&MK;##kG$)9N3wgbId)MQUWkQnz z4Ra3sgCwz7M&w#4zsO{z#+tkLQ9ZxNEqa#CwcHc_-?oP9FD6Mq#AwYrRzWJ|WPZ*` zZX>rR@$GoDO3b#vrkmyWnDS;F?3xyL4R^^egsyFj#C+hHt}o_?z`5xq7{>+;IJTVb z^S?8@UC_6;)zAFQTKj}{aF}9!d0XPy(0p8IlO%DIu7lIzSq0Z_iUI&WFt-K)mAq`n z>o;y3nC)0>F#qMwfGZWQvM!n@@7YCttT#KFHnFiMhzur?I`Bpz}wPM8zMh9u!>l~OZ;C^8UBeRec&aU*`)|T;D`pXaqzj+=~SG&5lUNd+jMg1kRUX#6g(VLgM0X%=NH!?^)hh z)lf1b;f8t4HCn=14h}(-=m%~X;M3s<89HKwa;u#SgA$*stEruJa}H@!YmCaJ%**LOLY>&9YyYvpx*AId=Gv+dTTu*JPL! zJbpZx0L%gmMwjnd9nH1=o@jG=?If!!gBXX$BAx`nL(WqNU@gkl*32Hrz^klOwA0r& z^VO@~tk$d)YFcQacFKl6U-jn^#-E*?y?XWP41^b`GtOP`#4{}B5sJ@9{pbwCl{LD* zgxA`imm{j-_b91W*v+TWz45JG&F1^3Jksk%6!89R=J_s*`?zxJyhm47%oX)%aq)tn zVi$NaBV28d3}?FQTpElot;nxAd&r-krN}b~V6N7aSxpCqo<>a56=)pqQKTA(wC-*_ zdN{+QU7o!{%HTE)K76<>h>X)%v{6yf(Jc>}i-3)r_wTnuI<2avq^vAooh$pA+V>5{TqK4Yb1T^_3ajOKmq)Sp6tDX~?b=11Jh@#s z{W%jS(U?gRcT)y+pRYR$Vi(|16tFHHwwvrNyms5EsC}!zx|t=JQCzH?las?kRY7m3 zB8jkJ5vK!$c@vZj6xIZ52GjErNp=vFD>9PKxnZX2!KUgJnQ@d{x~=1z0d zetpnx;@TypWZ5;DT8Jm%8r4ge>E`kQoW(Yd6xBUEoia}BtoQfp_JVTZDQ_<^sdlHS zdZ&^RO()2NfDUWds#PnYH4(W_%tBPfKV{l4-0TfQcfGv4xEjP@M==F<$E-6P7J(dI z+U3<%Rq`RGJIL+8l-r);u!D-B(uZM$G5LO_K$%R-x1)-3MgUzy>28VHA-qfk2+42T z%2f_UY+c`5+@-MxdD~gfpZ5@Ap2Cy6vMy5YpuIm(_1%E5$2ZMyS({2FW4xOGcyZ%& zROHI>75QZxu;d519<0KiYpfOi7F*pUS{Em%F@}zTtvVq{;&Q*m2VTQqoF*=Feu0P% z^=5;K3(xo<3xh^x0#qn+UKxLr6SezyvOiqt$eyA_A{^R{9o~HFQSmAj3VbJZAUk%*x>*7K z{$RoFYB7$#<=#+L6SKZq)?$dTVqX|Bgr1%MJhORxS;x?%ozXuNWO5ZajYzAC``+M3L^#%Xh-6Ut3$70b3?w zB_j?UI)NrzL3U9tYf-Wb3wr2fP1O)<3O5yZ888NC2;PHhFZDTs z5=a}`iGc=TayzaL^mEP#*2Ty<&ULZ5ake`1!EIhFqD4t;%9i?zD`8J3-KrH*8w8E=d-Uge#fGjbKC7G<0 z9Z!5jxr_9GD|1b>s{jbyCviam>{!MuuN6o+OVMdg$#pXm*JIgUYa)j>B&E2H#(1rF z@E`ueiO^}&7Mn`tC3N9KVICOWX7l+X?99!_kGrsoZV@6&5`d+XBb!nP`aoP(BX#A~ zbqCB?A6}i+ZL`zA^GHV?yOb6b=^8S|9~Yoxr_&?KIY+?-P}@ zAr|eH7MrH%L#q&wF(h6E@Y=Skmsm7E-owzk;& zZ63V9C1X@&uR;NGb>kN`mSxEP{kBz``0oh@OWx59IxSz`7Hhg*>P;Lsy2uHIO2Hm( z8i(h6fE&^$$m$<>>v=0%vC*L_TdFvI?=HE3pDj2haG^Vd&VgjbdSaxFQa8 z^-h{8qr!EkTb3+8l6&}cLP7`lLBPzcd-whk`2+Bk#ET4)OQiGjAyY?$57BjqQKdzm z6%VOI1XPwt63zRnDk1$MbZmE)w{8Bu@%xJrRtQNji9F}NSD&E|NW>HkNcWmZW-EJ? zF#5!oh=8Ux9Xi}bPa;NUEvv}yw)y^lfZ4K>FS$Eg7|{bPbapnTQ5vXrLVzaBx2jG4 ze<3HKdLAuXwdy31J+BS&8bTw4@7RYsd$MFYV4tF5A#W;{BH7x~()j!L?~fp^6%-WI z7@pL^$TBtz$fS*Q?dnx(m5z+)u;6-_I$&QRsw)AQ(anUVjSoxBuPIHRDQW2I&vDWp zG-!I?que*~%&8dNr|xS$)BM`WL^4a%x54hbLtp7D!qKAi=0DRUu6`GVr9d0JwV;5& zK;QHVa`C20?|CmKCQ8V(Bn>=PXZEI~akXH&_bc=V$XyhfKQ1$a8 zOjBMG@w%JGrv;roKP$&^a(HEo{`{`IdNoOaCN_4H`e`;kJzIax((1#-73hPNR8(fN zW~?dV7kQwyV&q1OWeHzVh_`2PR)jzCs4JJJtV^}@P}bDYuvoUmCTj5QWW%=*U8CFl z*_z*a4BzBN$9o1UaxWNTBA3cd!F#bBkN_tdyldC4p`XgiCIUvQ@4MSZ60brr1SC!X zl)ym%A|prc_cLprKv|^kR_@nPE>AWF!@2+h)lQI~=&L&8AkVkHu8zOmvZZ2Sv(Ia6 znU<8`xaGGSHaD$pVFcEuxaT(0;i`CWS&TpRWqh!?b7F)LYxCr+Ei82EblEM*WI^4LUCyphz{GP6_hd9TaAKhlKO6$xKHz%wvE(YN8^tAC8l;!7w ziZf?!Ea#((I54N{tXiU$G%o$&VtP|n)-R>`G1vj8-IAAAbqOu==KBi{0c@SVa!BuD z3$>6)gnW|3bn@LFC&!&Wy^Ct99}P`L^Yx)D&q(gN_gHK>i{zl-qUI_|LS;Yi`Z`5J zv@{d&{|bpaJM3mrQ74ECg!L2m_8CVwmg>1ixM&8Awqh$!p}a=irt+FJuAB5Wx$$Lz z^A0;c9Bor#IMFwl;lBMpX3JAkbZkW76FUAW$2d~22g?d1qVZp(wFDu3~*n)RNjnSKJ+i}*? zJXOhT>Qu$YBH{*wOa4`C1u-~UA3IE6CO<$;pK-LprxfeKXz&8ovi3UNAv5We2p6zD zH2EODUkxJIxgTO_BksA;7cr`4>mb*-4?SEzx>|dzJX`NRt9buwp1h*e!icE>eHn1X zWqdQ{Y!!gl4i8BzH5#wJ=8X*vsgGCK4scbO>uzYb?CjuGJ?XK{M30>;XNMTB1%0ta zw^K`r*~CII5pz0c(P}I~qLz1k?7n{ePR?7}vM(Q>4HJ1}f0LLaaWnt|XLF+o9io(A zcs2@21zphhBE{Xs*+8@{q^oWf0Y!DgaXAvfQ-G~i;h{iZusw#y%o;#HfxVAUaKe1~ zMb91Y>0OJ>=5=#9G;_c{CvHQ@Y<_kZlF7&bRbv3P^q25pR8(%&u}XSY%2!){H zy_!F}5z*F)6@6TKV3wO1U#gnbEv{GV%!~cF0QBTdgNvBPXM^(H z81VgVCB;-i{7X<5^azl5ttC`RXDqG&xZ=)MIB4D~^6R@_0BgSA`t|F_Ox&PtvaKOA zRRI1XMlA0FOH<-mKRqgByKc;EaX>PqT2&3m-!kF}RzY#K(XjB{YC8Ao6+~|;HW1yb zs1NICk+VSVI#LeMx>BgiGDR@vLKB}?Qq)W`XTOS`8#rKf+F5n zjeJc(=d{trMAlqTP^!$z4iF`=vl1 zApj=T5YyEx<0t8|-CfN76KlleluwBFG~ZTv_qM(GdS{Q!_)IP3T6A}A03hsg`{lMT z%Ja7@7xc3ELA{nV;(?S*7BaQ0i}a0e@l&;y`buoH z^Wk3E-K}Z_ zJmVgIiC-lctCjMTt0Lv=WI7AU#`BSo$dDNc_ZTJGS-|i-Ck`GNNRwV;*NZsMiFD60 z5-kEPPMq8IN=70m39bN4#fSLHj(9IQ(YM#G+!Qm0Qdog5S!aG)FZkb1b2N*OvKa(= z)va4MBejs%+^Tl=pFe)oSywiG{l{(s-_XI2^h5f;*`NvPohD41))oZ7_(x^e`$xxi zh44lBo5czh@fBJI0VBz-YvL`gUc2@tUF;VMZ#@rzw4hGtbS!ys(9->znhTiD(18MH zJFUb5guw}6Qy`83ykmyuXJ@yh!t}A$$`&{n#f2a=s1ig%w|7zHbdU+*7!%))n%_FE z^1?No|zO|?SU_ptv$=95+zju&wbfjx;JbU}|ZjV%3Tl7Ma; z9F7b<8XDR{G9FclFU;vk*o6xh+>Y;UZFYRh$WfybF3ey}?AWuXy?FcxJqUWC#_NR+ zkH-JaAQjG@lZJ{10+FraX=JQRtTB`-B=?6Ur z2C}3iWekEu`**)9ZKk&lOZ%d#swxTO%FoZ6aD;2yU3H7aRD;^j@9aX3AMYU9U-`E? zWI>qCpy4 zsSyLa1Xgj0nmtp=jht~iIZdbvKe$h;MMxupE5+T!a}m=z#O!$inZIY^FqM}qpfM_> zH-KECduD^=rSu#PtN>ds?jnjp0Znsvsg4}k#W~Ub{T^Ym^~-jKo_)h<`t$Yn4m%8> zq@=JtJ0ilub_i?`p!Yq=lGOJt04GTTAOyJ$Ycq@EjSSH3yE>?-p=93L^riLA_Pqnp z#_8pI3XtmDN;;{Dyl1-nzMcFL?Dr1}I=AxuwGw-A1A;$Li4=lepnT5Y$Yf2T$P3BZ zL~k#0iy;&Lp-$9W?Ec_?Y5@fPL&+*h`1VC-!xsZT+-A-1R!*mwyA>0& z{~&`r6ZPsLhUdhufVMrbskhwRIde`BMIhKifkMLliz7vdo~5w%YHC}LwSpZN!+c%q z$N-u=VS)^&+)gek4Cu;O*@g(tkuaWcO{)R>`toGSwCnsX??&~Vg?f@V)??dq_A-(n zb46#0fg+PW3p7f|5&^8p1&N|*gT*PM*)mzPCb4dV5?6=*Np4h_==1{Lu;O++TVu{w zA$_}&xoQ%cG}!kYOB;rz4GDn!KYX|+fkL|h+QqE`{Md0nX+bARZmu|=H}61qm;AUV z6KVq~w7!5EwS7ps(L`fopP{elechhS**=>V1&ZCjTz5g9~BV+!hnzM4c8b+R0WXLEuYx@^K*BSE9%j zS;>g-tuE5mo&-ccdp>75qsBCFz01*i7;`PJ`S!skO6X+IZr}d8k|a)>zVCPY`B`lA z*fi;6|KnrUwu0{Ufw=H4GWt$5rr@tJCHoF01858ff)S$azwmpCht(Z{n|1P+L*p-5 zEDC#Hmy6Fo3skK3=NFe==vctYZSW z3nCXm7rnSLNWj3zK8}pr+(lkq9wk_R@~Go%N^$QmptoUCwtyIAr8{|fo1<4O{wvE3 zO8n)$eL+(~IAiyeIcvaacO5&{hvH}`&7)qG<8Y*I6w*=jW@7y&UA`>lmO*2SG??4K zSWXKTNUUfM2PI?<$aAupycGyiFThHmV`#McY1KcQzT)*0y7VY^g7~z6y|p5f#A&bK z>IL-vN?q;jueMe;-?kJ#*GYy|W1k7FYi#UN-)*ZrQ22nn=l-*k%sX#X``|}mRqvWu zPr&fn2C@#l=}5E5Jq5vU@8$K|F85^Gn;&w+Y#XgTUVRxce}jOb9$vHj-xV&%7r(VX zJ~OD;u)WW-YKsH1+1FE6n3F$pwmt0UEm;?Fq68Jo7FWFz_;>gJsZVzBS|0oM@t7QY z*NqEw{`>gmfE&``v;EW)1GB?b1_%GI`)5PvQg_o`~9!qy@o7+HrO?WFMHGmi<>CSkax_oxA&vXwXxe)gS2WbJ1HU;7IAG{IIGw6j&NuhO@wa7PGX z5X=d^$QLpDF143y*>am<#j%Th(#e<*`qRD0Gr%0a7VR4bjmf6kvb4L+^bM4bdhQ`x zSz>2XrrT677zJ=4x-xJ0Lr(bIBO3s|g_<9R$#L$r%N`{p&E14g;ao7ge*ofb5f?HS z-P@USLribUtZvstnJg47gre=l(McR>N4n|(Fm-ls^qCBOo8mHV9yexka72V3@y6>u zzwFNPjh|ZFJ*u02bW{;K`u_m(FhySwo#1A0qPLM`|)aDfSSW!{@&SS{FyRYB8i7K4;0>!^3 zTJo-3mNH>iTGYEN7%?!!w3Z{h42~)XGp4KvOTyeGttOC+2QH$l1X&|307iLA8WP`P z7f;EVgGihnxTi^ck(UU$90|A*z5va;fPz)H8F zFU_J_0`~9|%|9pLEshplw{lbNRA;I|C}lAyg5(b$QcUp{cM?t?aFgXuHM;ILr+pSg zer-EbErb>&5+POuz4eJs6xf9oE(v^TsNw7z^Mr zi^P)4S2`U06}xuAYDy%^^Wcz>ZM;oLCmE@h4c`w)j6-Z9IC4kYG43E2zIsPQ<&1p? zB^7MmNbdmz=eBvA%|G5;eV9*!-sO9szR3!)Yf zY!(^eIk@TP1>LIf9777PlA#a>8CCt6#KvB6)}Ti?WnE0FB%2b#{XOUHSK!55FRc(sT*4XHkRGS7eN3@HQ8KNFEn+QKQhR z27l)FUIm~R;(rKDwgXmMFq&ef5N0@(XgXmh&(&|?%96ZkL?gKq zHUhwirid5t=GBJMmeRVKl6micvDr0g0YFO58XVXC?#70`iEmN(=xpqwXYe~jD%;Rk zadtyQ(a1~R1qLC`YN^}U^*ZO`<9$n9-0Dgz5G5m;$)rR6!b4g%;w24s3ypR=Dc8TS z)J|}4KsV^rU$tSsW9thFGNGN2!VJ&%ubKS}1&L6&t{rmWdd!2%g0btzq(UJo#^k|K zDAZ2~V^z73iIl+2VZ4cngQA(b%TVCXtUONtGqp3EVJ5tb&L2m7#1jH?w|alb1D%iW z-X;$*L{*KGoRu&dSW1kA;&+y@M-YlAw(495chC65;L`dD)A?u{?`*Y=CH7yatB{fk zkc^SxD6zCtyYS|~&$eN#kdc7+ws9kraTy7aq9FAg5WeVp>5arOrLe(MrsDVy$^%LD z(SiKUF`qdesZzCmD`J;%{M_zHz`OL7ob8j~+zvK~n;!}1vQ$I!Yg#>$E)3qnz54|y z$_VDS!aer>%oSA-X{RhTsoX<=L}3?Q$famQMlmO$cU|+$Kod1FiySQNHgw8an@Yi; zpr-&?j~KUkBoMvt?HjrMI{AwMb`0C@VN@ku6hypfJ)PE@Dmd zh`K$IFlZrFmILbXL&O!89pHz~!-vhLS&r#;H#zAoz!=4(WFAu9plKz~4})jHOd!+a zNy+DH+2+6`QM8aQdmAK2sL3LSUzm4wbyViUcHt>gc&%k}DszVKxf=A@P*oO36eG{v4g{v5sK4skwk!$gn^ zChWG{!C)s!EORQDDF{veBJc{CpNT&Xiin8N+wN@R>zSbqUqJV3ey1#Z!5qVJ9PlD* z3@vCj^ome!`>sRbPTe>2a&_j1HfMJ(8(??n?EXe9uff~5PrO#G0)Pa!h70B)xaAov z4G5&B>U6Q<-7=&tKGQO!+Rt7bScGUT4`*r&A4~WK2;5nln?*{Fxs2BoZ@afeJ zJ5!$0Rx~s{6&1Mv3i&``7gY{!ipyP-;@O}l)A7NGYczd@e`}R4etsN(CenLi7nt0G zPeIZ^?S5x51&!dj_o|E^ASw0gb?$4uBl-pj!P~5-f6&q$IAs~TI#u`E>D-#*cA7T^ zd>f>x*%wa@bmqWBdviPvSr<7m`Rtw19|NR3+~KBms2MoNV9tdFG6K0n)zHw`XodXk z+4JX?mX@6q6;Tm{@UN#vTZ%vcnAGh&x# zJL(?Y0^k>z*HSQ)u<-Cn9PZ-3Q72%fIcQfh(`3Z>Az@yQu@9T?{_O>=Jv@&aco>6u zD%4{W6y&`5bJP&Qsj0uU57^k-n?gGS{X0~+qxDs9O7l2oKA;~%TJ6pU_L@KUP^_a| zCgP#tRPbtQ;&IEU^2Mb)_;dXHDD5$mK;|nG)(Ky*y^SOj$uTQFFUXkoseXbhjtp)u z#S=E;=f@>+dT4V)J~+Rxo=gGvpYL_EXv+_;ZX^dkCfkOP8NV}is`h=7kh`48X$*-? z{vemhYgecrXJD{nZOVz|+um=jOlWdoyggC0W1Sk1J@0VOc22CFY4WVnYtn=Z215V| z-|SSjTJ=q{O&T&k@J1v*kyOD)nB+4^XRVvt2>_S^t`d;5S;k|O?{6)kP7)5GuhiSW zm|EXPVw%uCVAf9zpY`)&uvhkjU?U@u~*?yTq|1dMBrxz5OwjTN&nj!}E=Dpf`M&kzD-VbJ&zdv7JXtY6Nn@q)_N1pVe&-H`Bo3S3II>%g zo=Zb^$N9Rmocy{kn(Wg3M&hd3i$|FB?huuWu7;ff^cjwWg;ZL@J;O^MD(~_}UTDIqYK5p2j?$2X_ zWlOwtNxL?}pHdgJx$cwx9ETq>HReq6P^oX!QM!e2^V-&CLjt#L17H7)Df#N9(zUCd z`th-EUTHmO9=|H|`-}1ooV7?k1CdI&;TXdo=JEYwcXk{t3&8Sr`UO~~)9A+yP%`9y z8*;i7mBZI>-$WF+MCg%INs0$y4VMVsAaY0eCdApvbuIF-nLjC^YGG#dc+NlE374QZ zS?YN#)5Ob{Cxxo>9w$?MbRV}VY0h=nQK~&}T8uYu-};gtJ%%p%&aq+IPqjb`Y5yOMHb(US5~-r!vSk@_g;IveCg8I zmI}G@IkKWU<>o!sh$^#)4W*WM+&C(d;74D>!2??yQ&qCwa@^O4?ukj+QFrR>T=IfHhud}AlG=up}c@cUt}OQluHTGmqVcFnYuKd%1;g5Py%U_83GqYxaI z;k|rIil!J~MY~^z&dQl}S+jiADhRB-p68FWwi{C)+r^rUGI;qqx24@{blMny$*b9V zSXF74Ue|8ZI?7Gx=-A)T@EAq$-3fC8il_*=8C?)6LW=F@&5ChTj}zwaWkYdEkvrLM zYNxU5KT3Bt{LUkJcSlUj05R~H554GaXn(32KvL1Vc4Lpx+?r5cwEvFf_xMnx8nhSG zv$fjw=PfkqcBdS>w1txgHE1|$F_dSbe&XGDJ$&1V&$Yw3uU4jyY8&Hgpp(WNnnbah z%%7ibs(q77)D_LhvT7u!_vxCTQsk(uM2fq0tfeomhdYhs$$ut^kt(G5i>OIvae`$V z(YwoZ<39Qy;XD!y!WQO#a-2;eI7nn>aEBhq4;03d&mL0fRywcA~V>K7NVZ&{gwfy14k%+wD)7uCb|q!ylmH z(BNQi6oV;))zo|deLg&nKU}khTXGa6VMv)e6>GZQQR1I?3lMJ}Ar+~rW^T{gHgpbu ztv3UEHDo+{lB+0+sir7{f+;drC69_KSNxIqaST)@9kll6e^W-4l$0QxIB+J3xc3K? z6XmWDni3UX4*gm7j|ZDowK5yD^PUV)N`3OGlnU%2OYTR+$*sR(Weq%k2J>IJOR|6n zpD}hFgY5#cWE%P`hDBenKvfLog|1HMZPiOzIh*1b5ydLeWW#4gac)oY8gtDr-?qwn zu&hh?K=ENbJVL_4}&F&*4ZHMtj%Pc~CUkz`ZG zOs13vSpzT8H(F0nvt@-D+jXQ{L2^pniPNXWw81el0l64c--?XwSLair&mq4N2kT3mO=iqecLt}%F!D2-P9EP7@-6d zQ!UY`P<9_e0dW!agCX;U0Ruz;Ejo}Gl-8hT+j)LPCnmM!IuyMqBQ3Wct4ycpLeJw# zIc~7^&k>HpSvS_NxW4{V0F)c-6SCky$~cag9B#s&Z+5Am<7|z#Q*oP%uYv#m*KS7S zqJ5fXY-cwre@MHig*d4G)m+v5#LR8O5`friW4}^e)s361vFSwr(OaY6JQt1<>Z#Rk zZXz%c>x@Wr7YG>;p0HBAXlB>FW0DcUGIVBSBSpZtGmNhjHb|xi2&hK< zWmtHC#+zc^>Yt`DAbM}%o@qpTd-MPEUNvv`@o}rj#-EK&(1Ofa$}QQ28=}9}*WY9~ z9Xsg@ze;o>f-nXK0G!PMM*#8?A@iuo1vCE0 z0yY$>W$YR;iGz-(Qhzb)9WyI^`ECNkL}U`pK_0Bk)M?XPxYMB91pdOJ5ze}6*oee) z!6X!k4Xoucw=dJfPc`>6&J=G*=mj`k1in*PsJS72rmOGOy*?J}1mb2E&6~4}uhVX0 zoO#BY3c!8>>R%BSC_#gVo^HCBlw^H)f1Ik2JR&K4ejS9VAl7Q&HRINTuwM&^hUIFx zB)~N=;DckptL|Dj>2X#;yRz3(J^wJpeV_D6a%kg87)W0h)^w*((!KN`wt)B zX16CMei@q}wT(V-M(%(t+o^8+R$t@3TRw(czBN=ZF2ssFkf250+<_1IA?j0+x23N? zUxPjyaOzgCqsAc|&NpFpDPzU>bzXlJbH=z>-g2A?%LPcZM>9))7^&2D$LcHA90z%N zjT_;b)&+<%ZEMGVYHE+_^cXvZxQnvP3EEM5nZETn7wkpIaL#9Zb$66K&vQ`<#D!F=GM3Skx}ZIkW^qPc=zt=@HW%As=I0o?(X^+yZ)*9a?xr+hW5^Qu z!2|JUF=c1~{af}?ikbFz;j>9J|HP5h>I4L zy$m+4KL5FZMJ)Cd>GF50**Q~a(z}mc|L?X3%jsG-%zY5@u=gei@j88WIOmU$=K(2W zQa!{s%zLqy5KA!l@(LPAk<7^*U*GP-SHq>tmvbAG){6f_hL-#41hx7zV4ty{I?bb$ zVhIbng$kG|ybyHRp^@`AfS)oH%)iCaWYt#(l@%tP|ILf-K6QlMu0#5;ZnGyOCio8Nc z{A?;N6o|-?G$=0W= zwW6s+%}6V^BpaMfs=bs-pa|-U5P`8m1M{i>)KKy7|Nf-MvPJyyM~`t&oAJHGcM>0f z&nV_8z&?ah5SORu%tI0fv4#}1&eo*wI#jPJNzvqkUUmn94j&)K?%Btot%fAX zjK=}kxKGl=wegEuD;k8?ntyrLF5#H?gzVyJWXK&LVmwqko~M9{d@5TmbRBqaRu}he z3=lz>(-MOEEAggP1@b4mv8s(VZ@W; zkxHEhWqJgg>`1n(Tp_FCxB1U!zepuxk6;9c+;6O!to;1F=zlQ)h~NbnTLeExIvD=+ zrYA`x6O}^5jQa>b*a8kzG2WV`OJmqwTvP}nz~9SQ0%C%;h{^o;(VU-4d*p)TfSKt> zIby!BCogQMaeVpmCGpKex^(FRv?dmI9YHoiDoXyrQj`IlBK;WJcN1fa?*HQ#8i2Q7WY{jb3!qCu)DBgIt%$A;GWUlUbGVE~3Sihq?mu5TPx!c$;##AdOX~&8B zkw2!ttluy#Y*k6_+-qS;nxO%|B7m*YN`bN8Lgjxy*6#yETBuh%3#W>s;Sg`k`RgT&fm}xyFI6# zZFrXm*6XYFB3ZNYgyElg$7@!E#ViMNAyi4rE;?CbYUnNY*%{mT=bPh9WVoLFh)-}( z{u(;DslAqA^tGlUpTV8eox6u`{nJ1HljhdnQzt*_eDUpDBdgB6d(OS=x-VpY$kojQ z&ptdId{M7(#rqwFi?`2Ovb6qDbhs(sqkdaz=l4q^uCK+ILJH^N0rbtoLPmo=RvYO>-v#g6|B*thR{b)81o zDt={+K|5dL2`Ft#JoJZb_6WMD8a7FD;NG}F%Wa2GJe|2~VNUi5z>)Z6#kx&NW0xkc ziXAjiWsG_5my_Mrf8P1H^@xpWn_Bu`zuxVeim9!Gj{oNMQKi3JhMPN%3!Jc~qgRAz zh@<>CfC5=H(A)P2xXxr_2{pgO)J>tQB~|Pp0;+rW?^j_8XIQoqOskmO1~Qntc3IjU zm`^d{Lkym$-M2ntv5gvE3>p)23p~;}j#W3epZ;@0`$G6c+yJ&hIjNxVmi`1~m+he4 z$@fpHw(+rW>#t%E`Q5VRvELg`?(d>J&Y*DV>)_>MDsJh1os*Omxz=vohfx`k(?(g! z=I8CQegABif>-NEjcujMC;Hn9h$O)DLARgOl0{s~*rYfZu~%)QTxd~%*p;s2J|$d5 znIH#Ht5G#K+&~{9b$X1}RGr)VY=3AFGxLnG<}Pe1{GL zM~}Au)D3|UqT$#pp9M&;dJMG_(^o)Pg)o(3UIoXL>gIrpRLsu68q{ZP=XIf`DWj}< z6hHR>oX*ME*xB#brtAg>;IjArSO@qvdFIT7I|)`AhX)UFFtXjGKk|301+Oms=y|l? z=gp-K)mk&Y-}(H#>FuTB1N*_d@7B^0D_=&? zH4R0*@9_$ZYAIB;AQBjIm{B<=&2x-Mh%GH0U+M(_{0wnA+b<&{>|L8uCq>;9`Ndo8BSoMr+8jP$6=cc&R3+q=c)R+@W^ucDIkJ?A6Bh>V4`go1z(@%UXAH% zTz~Ff=o->cuDfLU$)%1{S2V4jI^a;Z(rpLEw;7XH^Hw%AER39pej;op_M9A<;$=kq zEjqsB-OGAL$~wG&_zf5yZNPUdfP{Ym;1S^*k zkQ?X(eTk5IA()}G6y**2)Bd`;ApmF>(J%@8jfiV8SPCS0A+7(iJODKT1(HE6uFC=+x6(#v-5vA^q1ONY2zpNcikKk+P7|eH#psA z(_xp=FpupWJT`s$uz6n)A*iS#-tzot(G{`JcZrx3Z7IGV)pHKgXd%@?=;lhKIcP-gpq&)y{6i>Y zKiB~WtiWc`%JqLz$3;aZTzB$A#BRmQD5jfHGfbdTprXjReR~&9bTN?(pg(40G(h*N zQIYAVUR-nye14JoAG95{i$4O+S)`HBGYS-WH1q8l93p(ZIt)eNW7TDMogWz+dlx)P z%o8;<>_e9!o&mK95os5mZ+=s;(vpk_Ci21AcH@-F#`Y9zpQuJNPrQ2o@KtL5+rKs2 zLD)CIy(8l`@8`_dMTG@A_YD0gU1B+aZ}<;}D;v@hT}$!&c6L*Cc46VHKQGAZ{WF%I z&g0#8@Zeo~bQs!wCj$;2J{;GZfb)Zk4FS$}0>RTo9vQo#Jpdf8BLO^8idSN-ccoM} zkBIy;u{0-Vrx=b)E(@K~6dY#aAtF*d>TvBzQIY5aeFy2&pBw+z#ooMg#}9-9*JKV@ zyNF>TrSKNcd=&j6oJ-JcoXHgLKtP?KRfv&>PTar!S#Ka9q`9CsvpGAF5LQqDC!{{; z)pONL=bPUS`=)h~loa$oKmGmd_YMQ)4I7qtr|;Z4W0SG*`YlOG7Lk$b)BimB`2D!^ zeY>dxv@)}Aah>t=ITA&-Kk_9#JYfsqqUxR=0!+Ny$c*6vWT#3BEqRy=SwW{_Vz?YT ztBxI-%W6a&sLnG4=@rc1g+=#!P%5Y;cQXDy{yAtVO$xdyG069vec}nDh7v?G@C@uU z%M}eYGpG1pgvwJxNr6l6jMeG(s61K;buIZ{o$stH1~4B9@+BGqR!x^>=hiL#3ZxM? z=mr7|08TKBEa(`qDF9F=$66QRi50^%xL?apmm^iZcYOSD4tUvTW!ZeurD()Cl-|*_ zFRN+UyZ2FpdIq`ulfk+dk}D+KJ&6OY`Eao%cW$S1K(9zo2@%KuS1@0+XaKTLwUHxj z`{cD1^a7v0|B%LCe|nm5?}k!jyz}_OK_isq64Vy!2^O-a(faH$>1B>d&e;kOB!L0} z@Bxy?)H@s`y;6%I&Ce!?)U}v-GSUKGI6B zaW`MB89nP|ca7yd^YVbn?ZeGlswO`mW#NvMRrxxP_6iEl9LY&b3XKgvXKVOV$_m6D zOZb5UcE^@h291rkiKEzQLFr5y5k70%7d0HujO4gmHhFpR+3@OV(#5$x^8r*(ec$^d zyMoXSu#Rn%#R|U0?KMI=f2z&aO$S@5IRDn2;YXLB08z;qp-dGKY5Y+Tki0=@P$Y}E zbyyrMKRQW^#uisDUThJZZr@hFtM~Nn|j~B950SF-p z;A5LZIS3knKIq-ay$XHaj38I{Q}_WoOa=`Kq9%Bp?Bof1@@78xF`v^=u*Tv&Yimy% zG!v=#ShNEtSP5b}A8T5F!)KkEhk$`#pto2@+dc;TLcr9WzeOQR?GFQ+!PYSSIbVD3 z7Qo@1h@m(Z-w1xW-`I4sO`Cqroqt;OrNgC8n!`FD-Xgms-L-LSth9LYl&D{0H-Ge; zQ{Z|cy^me_(v($ipR7_86GOWWcCeVc0ho!CdSLQ{3WGs%;vka1wYmBF7qH8WG=P{ufY*>-^h5(!wK}gww{U*g)=iaXPQF4?}112wI zk_!U;clq(x13<>ZxI3t-+cpi=PpDSfvGa3t^v%b;Ym&Z=>i5ym|Ib*Nf-C2DSJ@{& z=`~Bi)Ysz9tH67W=08?Ee4gmCOU{%9w%=MSd>v(FEJs5Tl4Q`{Q}8sV-s{M^;H^x> zpt28`H|*H4!Dx0(i8BlZw25Y~PZc7oXO~V>dXA9~=9Oy1T5CZ~%<4qwYkv`-*-4cH ze|o^4J^Q69LWTCxwfzOhOTG*7oxrT;TwfO(78a&1Mlbh3orU^LAaYXyCHBE?M`Mt@ zQ*~_g8e@Si=fjS$ZTlPPZ)v(3cI1c-o}@cZMqndYN_$d=OgYVxbAYb^X+3Z$((Y9@ z??S(>|M6*FS~|&LIx+&-c1tC-L;M*oaQR@A(B)-BX!U22iOiZJ4%Sor|7o>Oop$9%-*MwoEgHvr{d|E+O$&C#&8T{<|Db07>kGQZ$r4uS9 zEY%rbeC<+^mC8)bWm)!`E5E2|4jV9F^Tb6v!!E42q%^|moYJ`Bd1m^xhr_=73{m=I zI3b|Nk7%Xj)oEc}Jf{TwF8Q&waj}{F*yO2&onM_gBkvOZ^K#s&bJpSN(J^Ma$NE^- z9p828ee7q;q((W-s@lxAH(nd~?SHNIn5L1ZP=&h`e?MiJD26WUMnP$bSUwW+=&$cn zLKPGhi4iZ5v7k*$+2{`*JOJnw*fvig);7Kef1hUNgte9sqd>!;R1cs&5VZrfh9H{2 zZNvaFy5iiBU2CzNULfFBoQF|SeW@$T)0=+}p*7`R7>0Ql7|3YOoI{@X@@9^k@Aw%g zmB!+&(AQ^Vc!S5>c@lo$$mwIKz84}RNI2>fm6WSFkm!7e1d4Xa<47_6W!i_ zMn7vP0fW&qQIkxJL^0>-(5r0abEbOly{PRU0DYV(Z zJU6y;w+;<0ZVrBB%8(?>IXyNFnrAev?ae-^!J+%^wAmV*+8lE8RIl*?6B_qK1ofCW zr$D*WhEGPJ>KETSPt{lQF7%$T2IEZGHC)?$KNw9<1DK z9v`}_KzD4g!w27bk7L@}f4b{mZeC$gXsH!a^rzk9vrCW78))&qIU#M9&m5mg{eO;I zyLz?o`eYw%C)8ZxKe^qDquZXDas1Z0w@OLNXYccT-@$rub1S1umi_h0{lL{y?uDH$T643SESP^2Uh8kCfZ2$?FgkV2W0p)w^xr06^^Ywz#l{C?;BdG=%N zz1OlD?$3Q+_jSGBujw5N0|!!3RSOJ2akCGyKEYN~sEY7r)Ih1^-J{h=rM;@J2MzH1 z+;_}BJFslbKCgP8KhnR;`y`KU8g=}{{NPQpYcm~^XXkd`+M-YxzSpSr>+uKk zmt~dn2-H@cQk8U9xl`i(d#k~<$t86b9lK_99{Q? zR;7wYp8NkY;$Glm0-~w;v_yWW;Kfie8k?GipfvePMXY9#d`P1>ND0*d#abtv2U%I4 zdK?_ozrQp!2*`j)L1vMzO>R=AXhqz^xt$jrO%<4K{9_!1y10*w>GLE1s|C119YfK{Q6VcPM^O)S#3V-$D!sJJjhcqfpDO{l&YV4) zG~ru(VvPHWeeUJu z&EIOD{>UuKO5;;pJ#4%Cp!&|npSp3D0~UI!4H&TDR2TXEA731wJkZpN2%WM zo%d$6^m?(czn0dy0ka&(ocrJ_m;UzR)`h+O6Lc7WCI@7Q@Gm-4C9! z?ANzND61fM5!ZV{TXasudgrurbK^{|s%1qvIASI;KfqqBCxMYR%uBjY(I zQ@VaNbOFb0tP5;uH}8l47@z9)f^~vM7BD0MT)M=uP%d6uaB#gjup1(-8hEIhZNn~B z0wD;*xf$)3L^uKooaRG{5L#MwI^1ADe8CV%fSAq1K7Y_?fT3YL1j2D}JcDVhDmU0L z#-;4Q6*K+9+LgkG79DL<+GT$4ijxm#g5zxcXOPL3!`2CnmpFyUHUH;(q z94Xn7665>zWh>*OCPDhRp*5|+!p|(UJ#b>+K7s~DtO-{k#)T4ZbeC=PSWZq79yq^M zO+v}S4k4&GvLtX74)y-}TS7p?QZ3g>H7iX^AKIF z&{txHv`k3?Jv{1sA&v!RgM1L`bwHmJaPA^-n~o9_lL&5>se~{lHGDsvb5ATH6bwRn zL^ChM+kq{A>{A`PqrKQG7z)H~+%om-ao}~p!}G|gV3Q%nzewnaW|4#k*+4lWjXOp> z8}#U9j3}=di$72@@3ayaIz`5KK)gmE%c|e(1wtSL?z;f6Vnu9oycZx2zxZ`s-N6Na zzMfNraBKdN-;%;nE`kP9X58dKZ%Zu^So;bwB1Q~(w1^@f>8TtQ1RgO+Ujt)Y!9*{s5R#pOM6C*8EBfYa$ogr)|V zNX#=rH!apNSUE^#GAKSMC|W^Fl+Ls(SJ5pZ_S?eB0yxNHM-x~dolOF_kaGFLjqV1{ z6QT}{S_?GvZGVlGl4bYltPb`(;i6_P&@RzbL5T>Eiy9D0^Cer4Xpa$soB*l-OsYD( z$AE4^44oxCy(go80afnNIZV-ekP(TD?9<(#mx`-3S;0{EoYpGMZS~wp&u8-xp+CDFdj2}*lBOX_U!^EK&&i6qKWbn zb2lT$ZWr@uxYs9esS@3LlS;I#_&184#=`5g(c%{v8gHFX(#0n7Fw7qz)p(5s? z9wZEDn$bk?Xp#=Z2xT#SmMhLk`I6qmE2Aa?gG5}71m0*}n-mQJl&jK{0~O-BoW?h@ zo!j;>b(#e-Biy36Ww%jTp1`<_-Xo9nUN&Aa-VJji{ZTLuamsmeu#O=C6cY_YLt6`; z3)0wll~xwod>Dl2{NW4k#9ieWg0`pzM!WLlNgR@H14TM#?yxjVO1KeFiF2`sc|iqy z$w>(!{zg`MyppACX|J;xmBia%MOH$liHT#xM{c-r7;Qe{rBD1D%(yH$v%m|7tDi^_c{ucBYS zTwJ`J^G-jtqjr5{U8J&}_mm=dr)AdOHSp%4r4@2-OqKPUz< zo&vMBhdIU)E}Nt3W`rWQGRY)V-rIjaUDepqPEJ>xmkjms^;PfJZ+zx9&3WVG?ldk~ z2ndEh@<{_;9|0h>glziQ7>ecW5=TC9@E6ZtWKZ{we+V5#A?wMrrD5c47fIuO=O}@K z;&%Wsv{z7Idkv&M1ZfqlMXt}qu0L-P!U6~-F>s?Ds$P75=uokUFsY^?I5V8ta8K#hB`8%<;H70lA@> zy=s`c1*u~q#!2W06cl29tly_`mndQam||e10Y}LHvF@Q7_0V>j0O8@uh2WD74?Rli zsozyc_SDPY`+U}SatOW-5U?QPe8fIQ{{;Wrk)+!f(T^Sl4(fqSy+h=0iH!A!xB%eg zU6vjfZ5A_IHWGx$?=c4oESK250G@=a3!LsSTa)K?qJM7&x{&GfP&zvJ*=9Ne=KR#O zirpr9uYhhndL$#vICW|yl16Fk51)=&YY;J)KmozYoNRo5)W!63-#9F%YbXOi9|tTH zsb)rhe!BNITw}~`Dkuw@5H42O4iGpCQi^~)F}#in0bMrEc9pvuDS`-9Esi~($Cq;%(wR(yu;_zi4$~)-NSp0X~<0V?j)1=cFU)d2}}58C<3_L zJK(Ps8V<{*wyWUph^pAwyfKHhPGaN^F8qrK@b&T%Fnh&6*=*wOuzr8z-$0ZZy@C8r zP?$gVaBB17Z00Pdrt{#i3H@{ZfXi8tcJg|$-wW#ZZOj*-vW_wAlg-)A7IB>$O%no~ zJ)U!*PhhhyVtvrZdYBf;vGq->gz=lZ312Ht{l-+0ATHhoMRj`$#(yE9zNPxH;_FfNFr<^H|qoM1z_VLSmFtD{6$6F&CS&{vQAmoz|?QW ztH}~iMW@&yv(;LD*Bdy8`+U*E%)uM1@y|bdXcld9J?#uC7lg{IghfOkj%>#|=MWP@ zBJ9VlbEGHyO&7!0B*{5ERakw|_|b^me9>qS)7&fy3Vup5ht9=`trKNB4K18-6yX5W z!Hg60t=JB_0!W^(U77enMZPtxKTf3Kqy#`~M&QK28t{^n4D-{r4bpA&*rCOo2na#9yVPyKq;gNhsccst92dX9QQFYr&ZeYN+$5E_z2Byqga9Rw99lpyPF-?|lQ zbz1!i5-a{VCck~ZbD{aTy;sC8gftMSFz^ky?R;vldK+(8e9!Wu7C<*dqfT#93(UK{ z;#${-i0!c^iy1aR9N_5-I2uJA&AyLBqewK(oR1RhjT4E~V^94`$B=yZu>ISn7AXC6 zyLjj%+T!~qC6R|y9>5iCP9U4$$k;P?k4RKEqEUXbI$%78wh6XDtrIuSm=wC_dES|U zApr;9b(!Emqb?qgKtc|jP{`>oGttb<)yr#Wo6~1u$7mZb5mgCT&Zl{Fas3$fjy1{p z>K3GHhqGtX6Upy#v4|1}3)}84>2V;0Z)SHJR^;oFa>%MvKGZTF?utr*ZOzrXHD~^K{o+=zGmKa z_w>DC$#TDfA@J|F8lxjz__!IL+)C|%n* zNy(<6iqBd};Ur)>=KzCXpQ+1EH1CRS`Y#k?U^d{)t|N9CyAAUz&?bl|Qp2SaGz=)b zNugMB;OU>Q2U|d?ejM;o{|hzsZQCmBQ_0o1-PXRA4(OR&{*~5E@ZGHaw5X^qB< zU}0?=yF75)4vnUJ7Bbg_lkwlbiWEwFIsE*f}Lo_MhwPHLH8d1zUI8qFWejT@-fL z^s#ltCwITzoj;P|gDaV4OH`^7foZ_vl72X6NT%(C=>rGMZBFUhdB~dyE-rokB754J zG3jSc^xw7o)d`2uTXwsOXSZfEWjiyy22$uCE)u>mNS@Mr_cY6%>tFpjIq?t~dnWWE zCtI}(jvQ9nX-M0Y@Slde6sl^CcGv87y|GlGp}t-Xy~&MFsqboQ=PZe-Owx>w?{d0l z-MK0&G@E`zgf2j0eAFp##;5K>+tzLUd35*Gr2o$k`eCV)X5V$&xqb7e$K2c&)ATCs z(KgFvFN+85^19ksVRdeKFTLR>RFxAvW-BQ8d{vt^NK1S7(Kqw-wd@8$sy$iNkUe%F zKxp@C*B0*C)5R|!Vczc-O7c^EH~&>p|L8l&b=qwC@~>|C&K*Nfzlm12IA8QOf`KVw#u z|IfZEYrhW|Uf=IahJB=p>gJ`duXR=EIi)%0;LWwYr$s&1KJ?A^Pz?J+$=O zYq^#jAATt1i*I@R+lKQK(yYf19XfdI{_wE261V*C=C|HU-_v$6zh2le=)tYnk|Qr9 z(L0lGhHp1HkrTD?PLDVG3hTZF{4&plaeJe`51CpqG0{6=cdGTpEtXtrD-fjr zScK|}1s@;%aI2EcmVTS&w3yCBlk>wP=v%nqj zh190e;Esn^R26B&On9p12ReXSmpw>3>TArQA4?DD4Zj(_#oT6*l)>e`dc(&@8GlGA z-MeU!S<7m*>Jv4IbLTm|X}mG~&S~pcx14W8W0lxAKeBwpsW&v+=EE+H0!!H4D*bnALIok~EF%KVb@vOLY5&9arz}Qh4R3?35v;8cEZS zZ)hzueajW+;2`7S}0W+Nfe}8@GbWS@HJmu|E#1n?HYb@w0Ws>$f5!bpwwi zE$&%eF?5SC^%58ca@Gw6} zFBE?ESrt@Vl%4qQ&AkWdIu$;9I^SOS<@1{JtE-cfl7hixOzrG)Z?5#)uNYFeW)zb^ z*01bmzAfSW`JO^kE*dm!ts>_4#*G^V^!z%AUH``W2mUeSBor+uQEK!@nL9F_L>_QVOyQ*&ddbFJ^5B7R zBlT652Xjof4y4uN=89pi$Z1u?4?#^=SyQuFtQNe7;3REuM%ZQ6GM+oDH^iyu$jDn& zq}?;fc_ba;W>6b z&E+K=|0vRgo>Z3x6sRp_<~shjH7(_`<;z7{WI}qnJQ?mlZ2k1~a;}}ynm%)8*8Gr` zru-JH=dzX}DdLW1W!TIF2UQODCA($mwIEuWj5(cXN(ZMlFAsl9dG z`;2^Y!&S$j10cg?uBGDbm?dDR|3JNw_>{LE{OKAfO6kQFcW&D&_3YUmOC9>TN`P?T zj6)nwLi)vr<(t3!NkljM+a+)GhSR4jn-~SzJ`#vgPsZn>VE-yLRsuvt4kKUP8v6ev{E85|LeZDVNw*(#C~`mXKdL zAygnSXBmnnWZx>{>%srFL(%jdJGK`a$Ao3eYWIe;ZV9(8e{lH8lYnl7ph`rJ_=Yet zC)*nx+(8uYo0=MTE=Rtma^(@<0CX+wj1Dq+tz}f!w!$?pT&FHm(Eom;Thp;pbJ>tD z0mpEH4skryUhGDb)YErA$Vy0%@T#`%c;VznHZNCCPkDNGahq4<^`sLIvDUZ(zaeF7 z=-UEBB($JKMMYx#3A>;eVhrKhT96Bum|=_94+zVlHfXD{a)9b{CFl8(KLUej1@Omil z#vjP3m(kOVUheKOL|a=7M-tgQJnHkOtkgSMWO_Z!%{C78va_{4#@-H>`;rG!ZGOvT zVk{VFBLAIrZq-nl5mv4&-7*aE#Z@ojr0YKpnPe07V$!MR>WH=Fo4#BuxRk?OFmA%)kRfRBpzVE6f-ecmrRNtB+}!BE}Xk1 z!s$4G6HcB~7WW7>tXMXPSNfq*g=}YW8k0c>>_?2GG(b-Kp8qJ3V~ZPpA}H@Noby5l zh=E*2f~%nmrR7AjT;SEVi01)GB*JTj%@!=JBepdwH%IgPmBc#%A&Y>}O|ymw#-W5% zsVN7Ida*$Zhc4Su#?9F%78pD9mW&3pQ&(zF6CuvN3e|h1`_r%AzlY+Mmk8PMGusd8 zw#A1;b`#_Rqc1nI^*|3LLIOx61dEANRAi7d0v0>HM8d0Z1yeYapSB|?=NPET{W#al zD+2w5&<*9DniH+y`TjEdzBr9ABa3qZE&Q{#{&NsSjRu45M>K2$sn_RyuWiBh)&tU@ zeG#K>^#^ndKGLiH?v?*)0hVSD-Pe-er_`wOux!cJFIkt%<(6JL)%E-Jr}3j!75C^e z|3%!QMXMGS{kdrI)H~UmSpFqTmKd9TCN~;fWmLLWr!C8fV1PIgXXZ~_(QL`>@|?B< zkC)FH$wCy|9Zjf$MC{jsT@fRw#QsB2`v&szAe3d9#14@u1h?%*j2Ho@DlHLSR9btH zu}|#GH8L2aY_G`F;dT?5$dHO*ZSkFnvCtwtTnuy+UxrDgEm^okyY%CpAbb;X@-^}2 z2YauZ^WewIviMK8s-K-^Vh<`t0qV&&k!{!>5w{o+Z=T14NkbViWzcTR6pdlSHlIDa zHnWzvKGMaMK@&Gb-OCuH3n6Br9c%AnvN-wBAsI?49X-9Z$t4?^GNhf=Xy^5CUWlq6 z4qRJ1JK|ZNj{acn7ciic+(n|iF{1^CSvxy-kSNKAifrQ)|Mff16)I+ipEZeVR`$BM zXLE4E!RftQlrl%J+*Ce9QA6&eb*F$X170pDw3!k7D{`)N51qD=meY@oY3niSPpkao z-Y1_un;uZ7Z8^-PRZMJ%{I-O5`n@x~YWq%Jzp1%ke`HOyNm-G6utio-yfxocwfd9s z)uUsImR=cgrt`D-i=(=(+-$XZz7B6|vXtNQ(XVgiTqw64X<*O|%p>yVJpK|)MvXt( z!d?i<#oQS&p-KD5G-?bei90vx0{x9zQaUX2=w@nqd9*=+gz=nDM~^9xBxGf6 z=j$&n57=qh=8X2=yINXSwti@vGn)9tMM4HSyDw{N?+mD8_WLEF=twIbHGcO_DGRq& z`uhhZ=)Y<;X<$fkj$P%EQ|2!ZxEN2EpkcI1#!GcbaD(AAYaAI$ZxaAQtwIT zoE@>VVuq3~MZMda`>ZbH>MQN-thkHD&uXGo70% z%~SXH+kURYfZCB7fy)$&O!}#B*;2V^q49#Np1a2R2fg|{Jjkho<}lO8nfVFjr~B-B zve5MMT&JsVbtD0*(kJysj$iy?+V}~f3H5rDI(06vnI5V>SgNQtRAWbASk9Q!3G){y zUfj@6-#mQjgFku|Ln)wLSs&)oGgkUqOqfuWl017vOfDh6VvAa`q&;UFR1-B*gjNlw z9^BIHxDnejo-&vL&n#0r`$JBNt^{2F!l_TpbHaTeG)Y}d$>1fYEOM~2=dAD-%om5O zb6n%ue%8MhY;-yhEqz0-KB^P=aDve{pBwGkMShJKcIe1pYu%Am^X7HyR+&3fTJrg) ze^!T!lTIfUj7xrNJInTq{frKN7IF^Vx+mqvjCkXh7ax9a+;<(%!_DOi^NO4DyN|1n z|Cl;6d;DD8LaRqzlK;5s7T!_)&pv0NTc|LB_);X*c^-D}O)zNw^f%gQ^3pN)H@qc| z`io^NhK?w73tn8a{!@?SKZ}2;ty6iGVPEp= zeuak7`c9)=ni7UIXvzmDTx!!}q^bW1*{Z;CX8T(9g+%$xjT|^`f|j(Ywr-a#S8q7H z-_js8uHU*cy_0*Zq!}V4ib}0sS9_&wP*F_(+F{mf zje6b-_r1Yz6c3Ly-w`t(Eu|4KE#2uFmYi(7qMPlwQyX1#wAM7wywUJS{=Kwp;?IwZ zPR=>jwy4+Wkt?#DJM{SXENa95U({(TpECJGyB>1$ADH>{xZpXp=J)zfj;1>!BPBRe z*;1+^-e8rMlF%7^KQc49JnMU&Yn4NSEyQoW!NUeG3Syh%-cR)6I+*AwA1yDT(nAq*6FehmOBn;jP_Sb zQ7zu^V!C4Y?6D`Eb_ zKHdA9hdjJpZ*lBlf3ZLC9)+(>q~>N@{q9^xGs+z0=GfgJA%!^l7mvM&C;$QCz5j;w_r-39 z<}CQxXE4Q;2uBA*wq5v@J`Y|u2-ctG@_MbX_?F`85P~cr>4HBw#{S4}R3qJj zbN%hZ>^=`y4S@aH3+yd-z`Zw8|$f;0&67loaKKi*0+$IO+0oRHQR?`U4J88y<9#L{^MU|zXeo?d*pjP=pe7+b@fc7MFWOqa6 zm#|f~<0o9FO>Zp`V@WYBFk3trz8@o}L`k*6ho1{CD0aV?FC!U)Xt1>t_9NPL8h5mY*a1vX-9ZMX1L zIq^f5I>zmm4Y;nkxOCL((lymGqueVtw@F;Rm+-it>#vvhffo^lIr011yME`l zG>xN?eTmfrx1O-IzSuJA5+3C7P!zepkzQ7QS@ZFFeBl~tEDOiyUfwi1R*c;P*ON#v z9GvlQtY3V3k%vbp)fO$U8&>Y@p)DdS!e{w%>^EYzmXK`9ddHTYPjfPLAiz>M$l)Vt zWW(XMv9v~Lon``rNVVs|gl^v4h8=Dzb!RJy<>blB$>0&L2NZ=uTSC>3cwF@03@OVx zfRz^stvfB#TP*0HK5Y`zwmbv(0t5)br;u>$m=aIFq@*P1?Ag&kC80=igTrv`1##Gk z7z^Y}4!;ju>Xqi;kf=XeKIdCakgfcevRl^g7JVuIr7wG1E^7foSCKcQ z`SBb`#TvujOl5#`Ido%(@3G!J5#+C4?4xfq!Cfn(}y+2jGo zu@Hu?T<@}(l}Y$+{>~-t13eevGNne7?Y(0&wTv6lpQz+KlXLGb42U;c-<>?2@tma~ z8`;Y~Vy%-1PD;WHBrAE_+_^_wbhLEBrEbM{?@mP3M8fNy?oWYauTaC^$lUQ9PE2A9 z8U?xccNz-qcwEnpqC#S(#3qJ42^GkvN8+o0XD21K%5!pdpPgtOhI~cj35X67RTKia zR{w(-5Ur$wIwsrOQ1%6af$>&|ECA$h}=WITQ% zrPpmm`P%+IFP$RIQCIu+Q-&Pg)lLxS$MN?X%!;oP}W zXlg~UUd9WM4su@^-F2CO#e|fUP^7ubk}o6k5Oao@)+REZ@U?bt`pg6f;b*Kqb>YGV z5yum%$B9$v)>le+hsA6LiZKqKyt=5SA6mP$gpr>5(UpFhS5izF5*BurqnM$BL{dzM zMp)BYLT_3CV#7dmZ-4Esb+R*#D1%~(v|i@N-}IOh(2*XTO^Bw>M=n$3>VuQfgSw-+ z}s;QNc5?g7{ex%)*Kynq`un}_I)(}V9`I(Xz1WV z1M%9Dfx_%Q@G40H14nr}**pfrBuqpV5vCYpvy34#Vmu$a<{k`$@UNsQ%5E{6v17M~ zPWso<+p~kBI`!^l7? zO)ZB!49UEuOQ+%u1PU}4BN~2=e?(dCeAa`2C$cFxgC{W-VSsCqEQA zVzN2O@0}&18C~@JydNPQw;4QVC&Kzfs*OnH1}}IE+c-eti}0T`ewiSdR#NyI>E{mw zYvHLS|P zME!CJRd3#upbfL=t7OdpmpS-Z(Nr$NQ|9~Xid-vW6c~GmadQjvd9l<(e5A z5Xtf6w`PqsVLd}#F2-Yem^3hYC+aLhbV^YUF{mL_5;<$gKwv$9hF&o-F{MCWB<*>b znJE)010)pq!N=xcy~3OqPd{fh+#&2hd>+b2R^CnY%N)^@`YM(1!@yd092gfk)y#}1 z-kt4TuIHUD0hiA{3Rh*gsu_`mLYvJE5rM(8Sg(Y%ZiNsMq$h)9UYh?Q+)qjZ zP#w&>ZDMM=9P2QeluBL*fsm2S5{8h=m?{g43)Jg1LK2o?8lL6gAm%E8PR4ftq~k|k zgM1UfoS3A_Su9O3W;nS)pR6)$H75WMGSPy`9n@}fMJg6iJs!EWgz)!F<|`g}!lTO7)v3`<5arL+2zQ!@ae08WrzZ{o1mnliz2s+hKnv`0y@?Ea}fM*ctV zy|Y43E0Mqp2?r|(su*hqz#y_71z`r{Ckf(&-MDe%zY|z6*%#iqW0hz`eURbg5l{Y$ zj1a*ytId_>g*-D;u9^Z(L{hZxuHTl2F0zzI%~`@L1hKZ!Rx=d!rSRa;@FW98^IO-a zcscJ{pi{9x3>W1lCPOBWF`^>|YmrQdkk4oKTp)7TIw@8g7%dsflM}@;D#o4RsFJeQ zy(Bt-J$v^SK6@6w&&ZHeO3&ksg0!KQ7f~w&^|g$rY%8q!Dx66aV}HX5*!DsR`72Lr z!LhIjj|;1)m0@p1!0qeIIZ3yk4+->^c|7FebcFSR0sh?RFJ>@;7Xy^h_?!6 zaup~rhUtPDk$G`D27+a<;Ezx+_0!bcI{83VWn~a&oXFG`xyz%T8w?uMW<{P;;spw4 zbp72pjd?^>4cD(vLcS3)9Q9$BnVJDan*hSkZjP1=_q2G!TA2tnt-RnjA_R}$e zbDn&EyXE7U(>-$UY^pr@^^y7M=ePPEQI@GJt!tVd9~FGy>)3q`Df8ugg7>w>iIbL| zp2Q=@8P=IkD^6_DxozuWH)VL5(^N^?niA0kQ<{sSRM>pjO2iC3iQrzYQmA{b^pB5^ zKXX=02Ld7^jKXxzoL)#3Dasb?|JH%2(bQZjsnRQJpQzvm3*`{|)AXVx`1)%GlM9EK z2z8Vcp!Z+bH=F@fyzFzSyjWxY-%2Ms`CI$Alf)%_W2Z0hdI~euI)mvd$7eO)JFDp> zhG>V*%1iI?W}9M4c9f01y_k#(nY4+5=@r;1hO9Tcw-Bsiou)N>xHx?`SZllqc$Q1T z%dA;HXFPX#<5krye07AXi~9Tp3;O?y5I>7cLqaN;Dk_C<-_oZ^k%GI4Z#<=S*dmqj zrdRsO%LIGo;N5!j$$$c6t?leWrwo+das4t>YhLUkwViKMR`r0=MK8Ar=_p;zYpShb zL+`Hn@$ze9DJxxij^BFwl++v^I~8%}%$e+wSj$Jee`5WS@$u_ERRn&O zUt`#QjPId8%AVtG2ew{fS$sEM_U5>|ZiYsE3_rWR(UY2EUeEnsJXU=5D$M<9(f&NQ=vcqIRjP9rr21a&% zykHzFXZolUdnb}!8Gb8Y<$Qa}P^GrY=4~^Uk}*!UL+Cn3M+*-<9lm?13kSS4m+amr zZVcRo5bds>s>LD7-&IWZ(7M}#D&WkLOynk%B%!dL=Xyf+WLR? z(q#B3wqaKkjyBTLjk4NuxvdlNi)Z43psFD8a*MV?8@uzOtpW*ui@A=pm*z3&#x; zG^8YAXQIVFj(3hN`Qekzv>}%;ze|?AHox=O?D_NOUnsv#(0%VK(_8XL2iR8R-+(&k zk-IA|dbY=zn2*IQ7?EL5fv{qG+Ys2^9)y;4rD0+0Urp3J-LBzhzkYnx8lqMu-o2{+q1NtZTQi>`}PUBLfQ5K>guj+nR|M0^YJ7ylWFE`WONq4qWpZC5rceQAEU3q`P4fd!|qMJ6Te|iNYqnoYEG-1{|(Po@?S9VbcXR9kr^>@(?b zrwZ73LSka*B@j5PW=^u+(bUCyB;+CD0u)I+n@p ze>$}r?x4x}0Q@t*gHFhoP0tj6^_eu#)IN4g*PIsDkbeqtZnqB`W`Fec98h#U)r)Ns zhh}#+ZjQV9A>!JSAJ9+~9#RQ(I8>pcFeU+v0a=QS!@_kfl>n$RgC}_h)zU_je#{+y z!sa{M!C?mJKhN`gHuHx}V!Q_$Cnqd>;hbq0&bCe7v}@nK$&$C+%w5D-OWuOEqyRr^ z8{FcYQ1%_7rPY6fv9Va=Dypi{RLNEcjrPA;VG!%f$k{NFAHRy{lebaD%+{+3W=SSU zSj-L`+DJuuCIEnLCtIogDkLjT_f&bd1j$@?d>o%Px0Czdscg&o@Z)J84vRdyU#IU% z(%1*)F(rq__7E4+%9t0x%#60=`hb$N^sEFiE?+^vV(aW&Jm6aTl&A)^+?#fK=v+c& zW}BH|4zMn1+2?(+pIQ>F4R`5vk=?+0HMLK1dq;U6Flma}a-0R^qS-RK!Ry^g{d4*r zfiDi#rt5J7Q>lTOjC^GG$?ahpqejJ^d-1^pNj2||m>u`%U{utl0m?_^$k!R5eYA*g zm{dQlKAMx%^ZU%J3=Zqi+i=!`IT_?rPUCRM9;%8nh770?1KX~B`XT9Jc1E?Y%f-9v z-5-p*Q|s($p`Tl;=iOXZ=@sUlJ)^qQG&Qv-)h^bJmzxwS=9^xQuasSwq4!~V)dC7z zTU%Q*GnJ{!Ji3@RM|W!kg*7wV6&GhI-uGvKDeRV8cqkD)4Wgdr6OPhJK2#L&YUwww z%zAgUy!z+)8$97WF>A`{nmbCcr7bkCd26+XZ<|^FYGlV!UKIoIsvF-k1`c|}4+{$e zjhSp(fJpAU(8`)SbP0b|WVjCP!`#n(2F@rCE_tIg> zM*@4sX$`%jT^G{1S)1E4g)iWVCVg&|nJ7nphFmXn$}hV`OBFxed3VwOVAHjxJHvb+~^f}&i@2yztFE?MS zuRmbEce3GN_fJcTo}b@Y^tvTAzHVf*jk9@ZVZKduQsb_d2Ak_w|DIB>r#pRiH;+u` z@zB?UeHuFzIlZ#DI(I=_*5wfe{nOW}ueNC&Flzp}?`6BugYeQ&m#TCciBnjD2WmWs zEqhjbj=9i9?o^2)&>Hzbu9+gYp3q|v{lzQAU$IA1^fLNcA78Z$PMX6bE%NP4HUZ1X zg9o!CKT1hddpOy+h1t`bZJ`q(9WA%mW*_(kVQ>3R$LakZS(9m?uD|Bs+=k4(yXVKI zeyrPfa*ka!1qLyCbCTz;&Ge?FQDQ2D0IzKJ_6WiL+_}|;gllic7d&-Q{l0$Ah{H|w z>)$zASjdTkoO){1+Na)=X~)GN9gN%QN9_Ct{9S_QeNIJN?#z48x%*}FgqY)U@`|6@ zwQ?rq@0{FP%Y zFBK>J{5gGL`#!A$4i{^*eI{qOxW~fnJ$4)&(5~QqNs#M3+pui2PMf~ z8#3_B1^^8ea1GDfv)bBTDZo!>H(C8^%~#4uhvayO8-0C!iGXKk-k9l7_PC5_01z+d z_Y!H9z1>}WgEq+5{IKfjnxJ;yUHrM$DH@xa{SnPHU0p z2*Hp-$#sus&s#dQ7P;a}W}*pwDT*I!YwLoTbrd6{DYQbfw2@#Q60C3+3SAG?F1!Xr zl*kZXK6z5PtqW}l%SjeCob6U^*s$!Gjlix6d}QPymq1a!pzeAt!sSrMMKU85VvMQZ zl>oJZ8AI$xucZiYM&OwnIWl4_74Rs({@%}P9y%2g=MUwP>I3`w6sq3%&UV{v%jEly?FLZxz3<7 zJ9UQ-581cR(I%sC;U=Z&xgJOU-ibA_AZwR-{1VCPPtV3LS~NI|AXHwM(2j1rgaTkC zB4Hw$vgPnkVtNef_kY$k3=u0{g!_|N%ORebdy&@K7;!8~n?cqZW{@zM^+G6%yRi7c z*lkFGUn7FJ9NEwGnEUk(Lg0h^do%hkc0`dt(w72Kh>DTO0m2fIJj@$Hb8ywkV`jiw1o=T$V%W> z0+nAK+G01m`0{0GiuOI^2Y~6wOLX-0ub}ut4yFJG68cA{>m8NZ=A+ldwL1CUP2x9K z$}(BaSiOxT&7mRqpMl+T!hI)2A525Q>9owsKbiW0eqx4jZTU#8mKJmeR-Rs<=LtiNK={qi>jHa4$ z-s>6~);IQ64~vYmeBM{D+#o;t^HLZ8_LLLz%>_Tr+etU!@WJt=;KbtMOw>EgW!fBr zpd~?q$Z^P($BQM195P;R-W1ImjQ?g9kQnIB4C3RnL}!Cye#LStPL$yiu^IfAwfV){ zcd6_LRk9#5V1!_p=i40b7QS{q2bd_8`9X9;ABK=Apv|ur>j&R&2*e*Oy&!({P?`%s zfErjRS3mX6?wKfDs{)`QxyM+&Qz41J!t4n>zx@4!!Qv7DE=1}EwYA8253Sp0$!dt) zvnNc@RtTfP^$C~@W)o!I+KY-w?XR_a@XZk@dlRC&x%kG3H}OAm9vw0N{$*X=4nXJE zBpZwlFQ}=&KEBJ8q z@V9>(fzw7$n8KYvw;Bzs3pN}_*9hh=plK2bEvHUR#m^lDLbR5P zI!L?8Rqo9nJCH8|bgtBKI=K)JKZ$}e*In!T>Hl&sR7TGN)RNdTLpbQczM0=FeL9dG z=o@EkG(Kv6NOv-3;C#;KUf2@1bbn+0GmUT zd-w*Ex@h4|A?pw2k9f|7Oan25>HS31fJdu;p+)CA&@bVm!_35wK(&MyRBeq zuf*2DA>G;q{E>OcQQXRo9mVYE`~3jX0sqBdVX$MVgr*-KygPnN{Z+B>)Bp4er^`mc zb?{Zl*(ZuB9Cm@pt>e*EB*2n(>L_@F3FhXSH^#32wF^j|+g!?Yf}5c4C>N~=MCk`v z#Zu!}@CeV6c~c8N$pla^=>nyGp(QR=H zEVN^zfdHiX(pHHkofQX-;N7Mf3tit_^leYHx zO9QC_3;FJ?!fkBp&26xHNoycmbo=gPxQ)SZZ!L=x#TUKdA4sb`A+8OW=~S- z(1*8CU^*2YycnL%3j-SfG1woih??4pWy=yMaaL4)=N5~oWIz*#6Z27!@P*WhB^1tQ zR8vK;nS@VeNT1Uce8B$0M7u#}-v4+E=sCD=-^$D-W>?}XW4{>vsP#b56ltrOc`BdP z3muu)atp&jW-|Z8YUCc~&$tNV|0MU|!GkWD#T@Eue|y8=+{0}3U`<~P+MRdX>({>{T&xFoN*b@qI0|;M+wQeXILK~J( zD+zCgJ8Mozj{*Hu-hcQnu5K3=@)#bI}UZ zhH~`H0fPpaT3JPGGw6w;8ZHr9N0;~=!BlZYF8*IyOZpBTEXQhbYNYlh7rvF4__Eq! zz_3k>wt3W7Te}0C%@wR%$B=T03OqNFGVyoz(WAFlw9)Adl+MsyauPbCSKD)mOo{XPt?dJuLVOEii*_jSU?V*u zs*t)AUr?54b}H+M*UPwe%ZO7;9tTq=3wRdZ`6m^l%63G64>jx^*E5<|aGul~7)Qe~ zQ8}Gi_A+MuJe{s936E>fv9yWZ!l?00XChj%r>>xzFr{51v64}w?eUlNCHzuCGTc^n z2Sy_*;q8)<2=^A1lQ86gH;HhSUHNXkt`)`33kV2cY}{oMAwyAe2tU}MK{Y8kf7{9P zij_~yR(KN*HtJz$ zRN@WvB`U*8Fw_ah*W33q)q9XjKLK7{NNccKh*4I2&a(G2r%&I2|4=*_ag{<2Ls>!1 zs7OwT&`wdE@@#V(j=aBBQZ#S$zc)DgeDSk)4~IB=>jNE??&d>r3JE<4?_e~Va^^Bz zbeM9CQ+!b8UcK(*&gs_K$=P`-hmO#UPy%f07&A%zB+xmWyK=8yR=mXX7AQjGmD5jkr_}v-9WAFJxDc|7Cwo>P4Q<#JPbf9|_b6 zOH=!^l2XNKtlewtQG}a=oqBtDCslXs+>D+?PhVf1GoK3*GYBPb;cRDU42r&q{4+wL zB^9jw|D8IUDifaRaf6b6=Bee z377AX+&WEJ=23t0SHh8tqvFPZ2wFXUF>28{qi=lVZ*a&<&*}9(t_=mJ`Rrl#D|iY* z!<`T3aI%A=9e&LVedbVD#GR*4^8R=1^kehLUbh?S1_}^K@a;TXDcdO%NfaEt`lFrq zT|dL#oHZp3j1wIM{}D-i(`U^J<9&j97HNh=1VS-ln3F}Kk*bsKsDf1!W*R@DFdD+z zwmEqB`bN3VO3KPttfo_>Wuhs zno*++OLrqhCAA;=yJb+J4owaZ7nRqw5*k{z00^ZZbSXi1YlMlp%)FU8T15N#|9HMy z&|c+(dGn85(tigZwL*6_-k=Et-V$I~iY|Z?44?n_i4zYyI60Tqrhi}G@OZ&9U9w$y zD_(QkHMF!sC0_FqO%eqguhx+OV&HLLcwOa7OV_irMsZ+{oR?&DhV7I;^W5u(+9!Bp_c z?xVp+RHA0sJ#TT7y=v)Mw4_;Wgh4^UhX_kyJHjuZb5cSS@tNF9_|5xKl;>_-{E8QkMtlMoQetwlG^?4nKq5hQ zf#&wP#@fFgj8Z4psXBk9|8+_Th=PXzNnCD4Se8R z33yzt2Qnof1&QnbA?ZYnL{;Gmnjp{&+NlkM<4J)T{NyltNiY>&+`(@`McpMtnyf?0 z^dz1K+HRq3;B$TvCM8Hjyz)VGn&^_3aWVg5A%rTo!wU8PGrXoxpZNC^R1Em9uW0NS zvLcr}JJXSULtF?^oZEoj`wtu_ODQDetfIi!FM{{KGSPPgU$HPZEl z_UcV_k(ipgiF=5CgC4g%m7^$;IL8I$EKXV+|3bNsFjh>vfCPQbi7ZmJxi*ADg=ObB zf;iBZJwo`pQlx~|DeCT*wpvfV#eEmX-Qta}0y zAql%bqkKgqn|X4_7|W}J4*Cb9HsEPh$Jje3VtA#k*^IqbIO#x7_^KetmDg2O9!9{< zE9+*}f!O-J3{_o&EBzhUW)-I|00nFX+~rB&VSAYok8k1?`g1YctU3pGHBG?Y*mm;r zTYEl5D{%hBem7;4w*Atj-^q31|BE(&<=i#=+McHRH9CUo4Zen?EMF6yqYCtj9$j-aEdVlhg(Mwp8T2?F|J zZ{59n80BmAMgv$+q<1>YDhu3J8ZHdy0?h3CS{xI1YZH?{8f!*XtO*ezr=LDerM_PC zA@ej&VY7@f@hbrWrm|9{glr0P2YFMKMETG?bRE0acguCVjBPEA<(|2QKc4wer`{u# zLLw#^EzZ7Rj^m39H1o=Kaqm0}Q5%?-59-sC;Xkd_k;Zy#$>23RM zOzU72!o!^V3voj92$y>VO&aK#!-ZwoR&)HTtR!n>D(W{O!h^Wrqs0jnl zc{@0CN8pOPr^08f_l56WsEqxY?KI#Twh!sA7YZa>ldwl@5{7B&1a2LXmiIe#uFVPi zvP$tuvB&!T>CD5{ygH+oMbnn8YIV8qEutzrz3)_ZKSaGS$^T}b&96M4_PO)qfQ&sA z#6U4Jiuqz2cI=quvDwF7T~2$B-PV-Rj~Jv!salN<8LxqEb%P^@LzH+g$x+p+@2Wd} zWc%s%Iv(@8%s%Y(psmf!E}m`LJlH-}rH{?+GWkqLql~g>^}^g;Cl^&6dEavK=DK9J z2d7r;RzK4$dVZGp>sPO4JWhNz!XkLGeT>@?ZF=hx&s@|Lte9}1x3w1zu;r4=p*iM! z_rYE_-ISx{+U>Yjy>e!+0||ZK%XhIFTe@~;^A*2epVzNGI>x=~;UnL74)c%ST#&mq z>T%-Vx2BSj)0rQYHm2E9Bn)Co7FK2n!%|A$`I0`8AJsqO@zFoo{mb{CQ=T2WZb&Pu zIipte-yRv*(7tu)bd9~UA9d)uab=CRa&w(wH!b_1&@NoSTZcxsvX^o>BfZssR7%-4 ztokS1uS2`+`G>UEwrf{6zpGo8+v6+tLM%XvqC z28XM-L^jrXO2QvzyB8Ik+`QSZ?v3|9+t>Gg>b(9&hbF0@+qoIXYoDubo|}AQ%zAm7 zwWBw^)mRZ2QLyNj)~wvX;BQrZLXupkSSD50_j#ny;o7bP=6@cyywYFPy}@*Ibnfyw zbJw4)^*MYtbF|@x)bXYtCx)A>RQ1shi<=zf+Ha#$l8k1IrE^ttr=+8yn>HogeqYu$N4<;#+LU=l$+Y8Q0uwbXbJx}Oe3pOD{mj8wC69Lv6|V1EXLTL@;`%Ya zQ>r8HHe5RU;r`WA8JU0lweuXLl^dQUos9`jYv~!a#L_}GLe^$#ht&9j*P6?O$qT%P) zC+SJqf3*N__8YWTZup$8-+hU6lk4{@(Qg%d8?PL`<$~3px&`B>>zK`vYB%)BK&!g3 zZIi!@pJr<7qo=$3?@u3U?Km(@uY1JFC6A+MoE?0MN7?;sthgTOmU}^Zm2{ivUxn*j z^)`fdi7^k!iW&AxI{$ys_9oC=x8K_MM=8xD%225c$xy~hnKCp;nTHHzNJJ7srf4u^ z$YZKdhzywtMTRKKP%?**kfIQYGQHQWo^#GR=UxBxUuUiNto1wVsrY_B!+r02?`vQC zy8f9NToq;@m0vu4_2-!syVT7Zdi$#E&%}M6ct=NHD(L;xzoNX+|3{|G%Zb;DBEs5& zJVA$3pfky@qUG_xr)Uq~L2Ijl!Jobl1}$3up^+T#{8YUrUaq;X+oON2zfwX-S3TP~ zG-k9u&AJ}q;goplWITS+NtH=m#*Mz?^5S|agG)A9I|P}-TjE~aNX_whcU4{0(>f^H zYjRRguS;i{((yHX>``?40;5tIMpoNSKG?2{NXQU(E7@8qKCcQh6MXxxKaFoOI_x`8 zdDSDf@6&x-+XDlQGc9Mf50py1xc26&f%fvOefb#fw|mQI@O!eT@YoEUSpoozq>} z&o~94h+>bK9F*Y0U#0+zZ`r*&|5YI=AHljS6=dJA;U#9{C@|r-xvl#VVG^c%tr1O-!SlLx5fa2cp8O5EnR7owW28eeMdZH(2O61GYPALON!9RSD zrjd!xz5ZFpMHQ;5i7#t)e~EkZ-#+^Oj8egYPafL0&br5a`sd$}=2hVMjqUbMLyW54 z#dqaEs_E8FL(8tq{ngB9yB#@t)D)8=MDQN9*m#S+4Ln?g5d4m!_e;n)K(^7*5y9vL z(N6&Hj!1|Q1%6bzL<1ax7~Xg_L<<{W15rf+3<&ym5D^YXqaBH^^Z4sMCx9&y+d+Ua zP@^&yV!1S2FrbS;2_)SR_#J<-PK9YlW^;9EW5L=(ulyyi2n*A2%Wy;`Jq>+iL+@Ab zY5Iy*Ao7>d6Smb$IdQjDQ;y=54;0ecot|BO!6H&>7#LT#b-vtL?2SX#5BIxwrJkzp z-`^|wjad^TD`~$YXGG0a_e+?_oa3r|z%_PrUTN-&#uI@{?6dXqr+sEU+q-C<9ynmp z*{Nn{e?Fx;;L*C8{s=n)}thPwQC9dWT$=2?fea2jkaNW!3EIfCvJP*-F+kv@8L;Mzeo z?9Nb5Ufz;ts27TM0+a=egT|^H5HO(78)YsRy%@`j2nm&+YZHAJwDFo(5dDd$Js(F6 zmT6me;5qG~ysuwkiVsc`jLI5*@3n9Kj>_Dxah7%Kgc2U8Ug%$OJT%d`VIWo}mm?`6 z^XftQVVmu*_Wxq{ey2Nlz2rvTeB){N(zU5;RASG*Wtd(YFPpk`|5v)Z=C3Qxe=y3~ z&2*DZb!_~tR6ASJj>ak}7Zwc{7qi`=$#Q+E{C}Sg=AI~I5qFdm)h8c4eoQADUr&*l zM$eO(hca6mF(t6sO?R}%{B*ZPo?gSe@?~&HOfsG#U-n=( z2lyB~hG*CZ^Mp@8o(faP@^0XG^FJfaV#8&stW+KsL9cXtcbm-lT{$t8#hWGem#f;@ zU5Nha_e-LzMa5BWsGh|?G1|glD9-xbGDA@g<+BfUryUMj+Z-CMf8G}}y(_VHRaTa4 zLVavb{?_^T5*J@b#^WcgpC7cid-s5vY&4O@J$B;2S!FtwQVK&Lt~b)JoZT-)QWpz(nXycS|kckdPLu9k5R`LRn{&^D^3+)1_7_TdL#zMBg-216YF{j_+c zdA@q?L&HT+e=#}&@Fr7#6j1D+Bc{c;D`qUxqVg*=|FrP04R7YHBZ@?mvVOX* zczWep)zlfq`oM#ng@^Qm#~U}}tgY-j-EeDu-N25{` zg22|p?9j)r22(+^8&0_ycbTIl`Y8r2Rf-@)KtiYwfqS})paw|teON7+^jCCG)!bg9 z{VnE0<%~zHt%KqYA)~g$P0ppAJ+|c>0`#bJFoRD5`}8ALy#;&Kmu(ZFZ>6 z*4=*Xt#tQ-@9pQPuUCDTQy-72j#Vfg5gVRRGRT}iyUY85g7U+MvGuW5pEORlegCzg zs=X-qy*!jvMT;0ag>r}uD? zfY_YD^eU2foOoPpa1_Ptr|H~$w}XzWS)Yk^TW5R~;?q1f=dQOoTQgyNomu8S!&4e( zmNGHDZ@i$-y^DTqT&=AmzOVm&gN1CWVpY`vGgFNxLDF>L3Eauz{md@H%?~^02R~h~ zc>1A7vBm1{P^@b%^NFb4vGm-%$64LeZRJl{u|Al0TIB7m`$drn^imQIv z?*Cc#oXTPsVj0R%(fM5PUhqG1mbhDX&O^oOk560@=NHMH`Dv!%!nV(bV|;gd6uZ*p zu5@?z$lLO{X7bVN1Qs%x>kJ>GEd~pXm5=P+#s0Cke)qYHRz7@g^!Yy)a$=IHiif!k za%GeRNxcXQ&39zd&)M999r)0?4Yc0v5a{7ccE>6;_wg)jW4^oZo(htDVhA?QBhsL(-eR&HD~l zN8P8A?+qDs7Pv?r(m&&qv5=!4i+-)?+wkh^+kO@NmCH+4hGt{O&wvPo0X9Lu(cx4- zCIFmH!pVAD-LF}GBu4meMbZKTKF=y)*Ej3!+KrBOEwTm}AsxQafh~6oI1*0HrUs(>EXS6?<5PR-d1=lJT+sSyT7yv|NIEj}+HbNodcsiHNbXGPQE0 z*vZ!!yq+Lr|W_EHAodOsx{2sO^Bu6CnhSuI6yvWimVYRB5nZQ7r6qvZYOiI z{dQ8cI(x%J$cT^kLxZ=&SJurh`d>#0v99Xp@YD-Tyu4T}!y)z9qE!v+46KesX-7xC zx8JI8_QCciGe=Y|H1F@amTW0i26-cZh47uaOt@M|fZKo~BCQ~vK=d`4J$XpZ38l7xpRAaOeGi)DDS_ zFwEmY?I**Qm{~~xz{|zMlLP%$KnX06QQcKCwGCZr*!PHw!H@$FBNzh)aDss%Cb32b z1o<6F{l~9gl>s*r=}!(3s-zy+K#s<1(-;NdfcDa9Ll>1Pnh2}#y9rcQmf_vwT|d)9DC zwf6ekhxBcGOU?QA2e2JYs8=o3FxNX4t=D#6^N8Kw;PfOOQ=(qx(azpj7;obg$to0% zP{y1V@r2LS6T~40y}w&%PBoy#1hCN)?OaH~^5xCo^^#){U2ee;YVoJ*Z!t^o$^}{k z<8S)_$=E|12NTTI@U}V(VkQnHV?gg1q%^{CLpZ-z=o}C;G>dF0%+Hd3(q6DC=w)WI zoLRq~Xz8VXFrZm@2FP)Ri=&3RI;m5375`wQ z&^kViP7K*9_l`StBgjtvV-&e$b-Ku@k4-#UJvEPFqS=ofICI8WQcsXi^Ag>X#$2av zrNC6a(4Idv-p8BZ`uN4i$2%8*TnuL`FpcXiS59kQ+_#A$8npn+qN8u(Dl$ucTR!Zk zfulkdlrDtc_rE=c^me>%&k*$L!~mXCAc)cN7PV@pHiJNR9Nm0meqt(VTJRYk7shmS zt;_(bMkxH4Ouv6P9EC#`(*;TB@#fasBlMAQ;o3uC$ByP}kN0uJ^X-h0H5Q1H`! zZ)K62rk`jXdIy&GmbR$p4pa=pDgF6Vh_&O)K9*85O1g>61XaNt*~{d(qjki@=r z6-Qw@_A9#0;XMRftKD58*;phUeC4KfCnW6-aQBm5S|! zxuNaS($Q$f9@B3LXbpWO<;LJS)407r z+S(+dRjvN?-dqA(r|0-Q)Cx0{U)mID&&-^ODO4g74aUzRP%LxQOMQu5HiS=%F(>un z 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 h{x0(V2MmQp-ra%x(=UxWttj|8q@t<(aKHJL{{. - - As a work around, you can use mysqldump during the cutover stage to migrate - those tables. + will error out during initialization if `binlog_format` is not `ROW` or + `binlog_row_image` is not `FULL`. + - With target verification enabled (the default), the source must also have + `binlog_rows_query_log_events=ON`, and the target needs binary logging with + `binlog_rows_query_log_events=ON`. + +- Every table to be copied has one pagination column with unique, non-NULL + values: by default its single-column primary key, otherwise a column + configured with `CascadingPaginationColumnConfig`. Integer columns and + binary-comparable string columns are supported. See + [Limitations](technicaloverview.md#limitations) for the exact selection + order, supported types and boundary values. - There are no foreign key constraints in your tables. - - You should remove these constraints before running Ghostferry. + - Tables with foreign key constraints are rejected by default. You should + remove these constraints before running Ghostferry. + - `SkipForeignKeyConstraintsCheck: true` bypasses the check but does not + make the migration correct, and `TablesToBeCreatedFirst` only orders table + creation on the target. - `ghostferry-copydb` can only copy a whole table at a time. - If you need to copy a subset, use ghostferry as a library to build your own application. -- In cases of a multi-node replication setup, Ghostferry should only be run on - the master database where writes occur. Otherwise there may be a race - condition causing some binlog entries to be missed. - - - There may be a way to fix this in the future. +- The source is either the writer (master) itself, or a replica configured with + `RunFerryFromReplica`; see [Running from a replica](#running-from-a-replica). @@ -56,42 +63,82 @@ performed this test move can be used by a staging version of your app to verify that the target MySQL will not cause trouble for your app, especially if the target MySQL has different version/configurations. -If you want to test the entire flow including the cutover, you can as well with -some additional setup: - -1. Setup a slave of the source database. Use this slave as the source database. -2. Use Ghostferry to copy the data from the slave to some target. -3. Stop replication on the source slave. This is the equivalent to setting the - database to read only. -4. Perform the cutover as normal. Can even run verification with this. +If you want to rehearse the entire flow including the cutover, use an isolated +setup rather than a live production writer: a writer with a replica that +replicates from it, and a separate target. Run Ghostferry from the replica as +described in [Running from a replica](#running-from-a-replica) and follow the +same cutover procedure as in production, including verification. Do not simply +stop replication on the replica as a substitute for stopping writes: Ghostferry +waits for the replica to catch up to the writer during cutover. + +A rehearsal measures compatibility and downtime. It is not evidence that the +data of a different, later run is correct. + +## Running from a replica + +To copy from a replica, set in the copydb configuration: + +- `RunFerryFromReplica: true`; +- `SourceReplicationMaster`: connection settings of the upstream writer; +- `ReplicatedMasterPositionQuery`: a query executed on the replica that returns + one row with the writer's binlog file name (string) and position (integer) + up to which the replica has applied replication, for example from a + heartbeat table written only by the writer (such as `meta.heartbeat` in + `examples/copydb/run-on-replica.conf.json`, or a pt-heartbeat table); +- optionally `WaitForReplicationTimeout`, a duration string such as `"5m"`. + Empty means Ghostferry effectively waits without limit. + +The example configuration only shows these fields: the repository's compose +file does not set up replication or a heartbeat table for you. The source +replica must log replicated updates (`log_replica_updates` / +`log_slave_updates`), because Ghostferry reads the replica's own binlog. + +During cutover, keep replication running. Stop application writes on the +upstream writer, then allow cutover. Ghostferry reads the writer's current +binlog position, waits until `ReplicatedMasterPositionQuery` on the replica +reports that position or later, and then drains the replica's own binlog. +**Keep the upstream writer at `read_only=OFF`** and stop writes by other means: +Ghostferry checks `@@read_only` on `SourceReplicationMaster` and aborts if it is +`ON`, treating it as a writer that has been demoted to a replica. ## To Verify Or Not To Verify -Ghostferry has two built-in verifiers. They are designed to give you certainty -that the data of the source and the target are identical after a move and -nothing was corrupted/missed. They are designed to be used during the cutover -process, when writes to the source database have stopped and writes to the -target have not yet started. During the run, both the source and target must -be kept read only and thus incur downtime for your dataset. The two different -verifiers have different downtime characteristics. See the [Verifiers](verifiers.md) -page for more details on what they are and how to choose a verifier. This means -you have to decide if you want to verify or not. +Ghostferry has built-in data verifiers, selected with `VerifierType`. They are +designed to give you certainty that the data of the source and the target are +identical after a move and nothing was corrupted/missed, within the scope of +the selected verifier. Independently, the TargetVerifier monitors the target +for unexpected writes by default; it does not compare data and is no substitute +for a final data verification. See the [Verifiers](verifiers.md) page for more +details on what they are and how to choose a verifier. + +Source writes continue normally while Ghostferry copies data. Ghostferry +writes to the target throughout the run, so no other writer may modify the +copied tables on the target. Application writes must be stopped for the final +binlog drain and the final verification, and stay stopped until they are +routed to the target. The verifiers have different downtime characteristics: +`ChecksumTable` scans every copied table during this window, `Inline` only +reverifies rows changed since the copy. In order to know how much downtime you will incur during the verification -process, you can test it with the slave based staging move described in -[Testing Ghostferry with Production Data](#prodtesting). During the cutover stages, run -verification as normal and measure the time taken. - -Since the ultimate objective of the verifier is to verify that Ghostferry did -not make a mistake while copying the data and give you peace of mind, if you -were able to successfully perform the staging verification, you would know that -the system already works with your setup and data. At this point it may no -longer be necessary to run a verification during the production move as the -chance of a row that has changed between the staging run and the actual run -causing an issue is slim. - -It is also possible to run a verification after a move and possibly address any -issues after the fact: +process, you can measure it with the rehearsal described in +[Testing Ghostferry with Production Data](#prodtesting). During the cutover +stages, run verification as normal and measure the time taken. A successful +rehearsal does not make verification of the production run unnecessary: it +says nothing about the data copied by a different run. + +ghostferry-copydb does not run the final verification automatically. After the +state is `done` (source binlog streaming has stopped and copydb has already +stopped the TargetVerifier and called `CutoverUnlock`), click Run Verification +in the web UI and wait until Verified Correct is `true` with no error before +allowing application writes to the target. `CutoverUnlock` is therefore not a +signal that the data has been verified. `CutoverLock` and `CutoverUnlock` are +HTTP callbacks that copydb calls at the start and end of cutover; +`ControlServerConfig.CustomScripts` adds separate buttons in the UI to run +scripts on demand. Allowing automatic cutover does not stop application writes +by itself. + +It is also possible to run an additional verification after a move and +possibly address any issues after the fact: 1. Setup a slave of the source database. 2. Setup a slave of the target database. @@ -105,24 +152,37 @@ issues after the fact: It is possible for Ghostferry to encounter an unrecoverable error (such as a network partition with the database). In these scenarios, the target will be left alone as the Ghostferry process panics and quits. It may be possible to -resume these runs using the experimental interrupt & resume feature. See +resume these runs using the experimental interrupt & resume feature, which +keeps the tables already created on the target. See [Interrupt and resuming `ghostferry-copydb`](copydbinterruptresume.md). -If the resume doesn't work, starting a brand new Ghostferry run is perfectly -fine. For copydb specifically, you need to drop the databases created by -copydb on the target as it will try to recreate it. +If the resume doesn't work, you can start a brand new Ghostferry run. For +copydb, use an empty target, or remove only the tables created by the failed +run (after making sure that nothing else uses them). A fresh copydb run uses +`CREATE DATABASE IF NOT EXISTS` but plain `CREATE TABLE`, so it fails if a +copied table already exists. `AllowExistingTargetTable: true` changes this to +`CREATE TABLE IF NOT EXISTS` without validating the existing schema or data; it +is not an automatic recovery mechanism. ## Configuration for `ghostferry-copydb` -The configuration for `ghostferry-copydb` is a JSON file. The schema it is -based on the [Config struct of ghostferry](https://godoc.org/github.com/Shopify/ghostferry#Config), with some -differences: +The configuration for `ghostferry-copydb` is a JSON file passed as the +positional argument (`ghostferry-copydb [options] conf.json`); unlike +`ghostferry-sharding`, copydb does not read its configuration from stdin. The +schema it is based on the +[Config struct of ghostferry](https://pkg.go.dev/github.com/Shopify/ghostferry#Config), +embedded in copydb's configuration, with some differences: - You cannot specify `TableFilter` and `CopyFilter`. -- If you are using the debian package, you don't need to specify - `WebBasedir` as it is compiled into the binary. +- Data verification is selected with `VerifierType` of the embedded ghostferry + Config. +- The web UI location is `ControlServerConfig.WebBasedir` (the top-level + `WebBasedir` field is deprecated). If you are using the debian package, you + don't need to specify it as it is compiled into the binary. It also allows you specify some options according to fields defined by the -[Config struct of copydb](https://godoc.org/github.com/Shopify/ghostferry/copydb#Config). This allows -you to filter the databases/tables to copy as well as specify the type of -verifier. +[Config struct of copydb](https://pkg.go.dev/github.com/Shopify/ghostferry/copydb#Config), +such as `Databases` and `Tables` to filter and rename the databases/tables to +copy, and the replica settings above. The API documentation is versioned; for +the `main` branch, the configuration structs in this repository are +authoritative. diff --git a/docs/copydbinterruptresume.md b/docs/copydbinterruptresume.md index 103cf9ff4..7af58b25b 100644 --- a/docs/copydbinterruptresume.md +++ b/docs/copydbinterruptresume.md @@ -6,83 +6,76 @@ thoroughly in your environment to ensure there are no data loss. See the bottom of this page for important information on caveats of using this feature.* -To enable state dumps of Ghostferry on panic (and thus interrupt & resume), the -configuration given to copydb must have the entry `"DumpStateOnSignal": true`. -Once this is configured, any time the process panics, which can be -caused by both SIGTERM/SIGINT or due to an error within Ghostferry, the run -state will be dumped to stdout with JSON. An example of this can be seen below: +To capture a state dump when copydb receives SIGINT or SIGTERM (and thus +interrupt & resume), the configuration given to copydb must contain **both**: ```json -{ - "GhostferryVersion": "1.1.0+20190311205252+88a1c5c", - "LastKnownTableSchemaCache": { - "abc.table1": { - "Schema": "abc", - "Name": "table1", - "Columns": [ - { - "Name": "id", - "Type": 1, - "Collation": "", - "RawType": "bigint(20)", - "IsAuto": true, - "IsUnsigned": false, - "EnumValues": null, - "SetValues": null - }, - { - "Name": "data", - "Type": 5, - "Collation": "utf8mb4_unicode_ci", - "RawType": "varchar(16)", - "IsAuto": false, - "IsUnsigned": false, - "EnumValues": null, - "SetValues": null - } - ], - "Indexes": [ - { - "Name": "PRIMARY", - "Columns": [ - "id" - ], - "Cardinality": [ - 1 - ] - } - ], - "PKColumns": [ - 0 - ], - "UnsignedColumns": null - } - }, - "CurrentStage": "COPY", - "CopyStage": { - "LastProcessedBinlogPosition": { - "Name": "mysql-bin.000008", - "Pos": 193989 - }, - "LastSuccessfulPaginationKeys": { - "abc.table1": 200 - }, - "CompletedTables": {} - }, - "VerifierStage": null -} +"DumpStateOnSignal": true, +"DumpStateToStdoutOnError": true ``` -To resume, you first need to save this JSON into a file. Alternatively, you -could pipe the stdout of `ghostferry-copydb` directly into a file via: +`DumpStateOnSignal` installs the SIGINT/SIGTERM handler, which reports the +signal as a fatal error. `DumpStateToStdoutOnError` makes the default error +handler write the run state as JSON to stdout whenever it reports a fatal +error, whether caused by a signal or by an error within Ghostferry. With only +`DumpStateOnSignal`, a signal stops the run without writing a dump to stdout. +Not every failure produces a usable dump: errors during early initialization +or configuration, and arbitrary panics outside the error handler, do not. A +signal received during cutover is refused (logged and ignored) and the run +continues; after the run is done, a signal exits the process. + +Capture stdout in its own file and keep the logs (stderr) separate: ```console $ ghostferry-copydb -verbose conf.json >state-dump.json 2>ghostferry.log ``` -Theoretically, `ghostferry-copydb` should write only the state dump json into -stdout and all logs in stderr. However, check the files to make sure this is -true. If not, file a bug report. +`ghostferry-copydb` should write only the state dump JSON to stdout and all +logs to stderr. Check that `state-dump.json` contains exactly one JSON object; +if not, file a bug report. + +The following dump was captured from the tutorial's configuration with +`"VerifierType": "Inline"` and `"DoNotIncludeSchemaCacheInStateDump": true` +(hence `LastKnownTableSchemaCache` is `null`), interrupted with SIGTERM while +waiting for cutover. It is illustrative only: resume from your own, unedited +dump and never paste this example. + +```json +{ + "LastSuccessfulPaginationKeys": { + "abc.table1": { + "type": "uint64", + "value": 351, + "column": "id" + } + }, + "GhostferryVersion": "1.3.1+20260929140923+5bbb419", + "LastKnownTableSchemaCache": null, + "CompletedTables": { + "abc.table1": true + }, + "LastWrittenBinlogPosition": { + "Name": "mysql-bin.036631", + "Pos": 276 + }, + "BinlogVerifyStore": { + "abc": { + "table1": {} + } + }, + "LastStoredBinlogPositionForInlineVerifier": { + "Name": "mysql-bin.036631", + "Pos": 276 + }, + "LastStoredBinlogPositionForTargetVerifier": { + "Name": "mysql-bin.032481", + "Pos": 276 + } +} +``` + +Pagination keys are stored as objects with their type, column and value; +binary pagination keys use `"type": "binary"` with the value hex-encoded. To resume, pass `state-dump.json` as a flag back to `ghostferry-copydb`: @@ -90,26 +83,49 @@ To resume, pass `state-dump.json` as a flag back to `ghostferry-copydb`: $ ghostferry-copydb -verbose -resumestate state-dump.json conf.json ``` -**Note: if you interrupt Ghostferry for a period of time longer than your -binlog retention time, you will not be able to resume Ghostferry. Ensure that -the binlog at the position recorded in the state dump is available when -resuming Ghostferry.** +Requirements for resuming: + +- Use the **same built binary** that produced the dump. Ghostferry compares + the entire `GhostferryVersion` string, including the build timestamp and + commit, and refuses to resume on any difference. Do not rebuild between + capture and resume, and do not edit the version field to bypass the check. +- Keep the tables already created on the target, and use the same + configuration, in particular the same database/table filters and rewrites. +- The source binlogs at the positions recorded in the dump must still be + available, and so must the target binlogs at + `LastStoredBinlogPositionForTargetVerifier` if target verification is + enabled. **If you interrupt Ghostferry for longer than your binlog retention + time, you will not be able to resume it.** +- If the dump does not include the schema cache + (`DoNotIncludeSchemaCacheInStateDump`), the schemas are reloaded from the + source on resume and must still be compatible with the copied data. + +If there is no dump, the required binlogs have been purged, or production has +already been switched over to the target, do not fabricate or edit resume +coordinates; start a new run instead (see +[Dealing with Errors and Restarting Runs](copydbinprod.md#dealing-with-errors-and-restarting-runs)). Some other considerations/notes: -- While Ghostferry will dump the state when it encounters an unrecoverable - error (such as a network issue to the databases), the only tested use case - for now is due to an interrupt with SIGTERM/SIGINT. +- Verification state on resume: + + - Inline: the reverify store (`BinlogVerifyStore`) and its source binlog + checkpoint are saved and restored. + - TargetVerifier: its target binlog checkpoint is saved and restored. + - Iterative (deprecated): its in-memory verification progress is not saved; + verification must be repeated. + - ChecksumTable: runs as a fresh scan during cutover, so there is nothing to + restore. + +- The integration tests exercise resuming after signals, including the Inline + verifier and target verifier state, repeated interrupts and resumes, and + processes killed abruptly that resume from an earlier valid state (for + example one delivered through the state callback). This does not prove that + every failure is recoverable. - - Errored runs *should* be theoretically safe to resume, but this is not - validated in any form. If you resume an errored run, it is recommended to - validate the correctness of the data using the CHECKSUM TABLE verifier. - - As the project develops, we want to validate the safety of resuming errored - runs. - - To test resuming errored runs further, see + - Rehearse interrupting and resuming in your environment, and validate the + correctness of resumed data with a final verification. See [Testing Ghostferry with Production Data](copydbinprod.md#prodtesting). -- Verifiers are not resumable, including the IterativeVerifier. This may change - in the future. - While we are confident the algorithm is correct, this is still a highly experimental feature. USE AT YOUR OWN RISK. diff --git a/docs/howtousecustom.md b/docs/howtousecustom.md index 09ed36077..3e0f26878 100644 --- a/docs/howtousecustom.md +++ b/docs/howtousecustom.md @@ -6,30 +6,49 @@ For an example application, see [ghostferry-copydb](https://github.com/Shopify/g ## Consuming Ghostferry Metrics -Ghostferry provides optional metrics to your application. - -Start consuming the metrics: +Ghostferry provides optional metrics to your application. The following is a +complete program that consumes them and emits one metric of its own: ```go -sink := make(chan interface{}, 512) -metrics := ghostferry.SetGlobalMetrics("myApp", sink) - -go func(){ - for { - switch metric := (<-sink).(type) { - case ghostferry.CountMetric: - // Do something with the metric - case ghostferry.GaugeMetric: - // Do something with the metric - case ghostferry.TimerMetric: - // Do something with the metric - } - } -}() +package main + +import ( + "fmt" + + "github.com/Shopify/ghostferry" +) + +func main() { + sink := make(chan interface{}, 512) + metrics := ghostferry.SetGlobalMetrics("myApp", sink) + + metrics.AddConsumer() + go func() { + defer metrics.DoneConsumer() + + for m := range sink { + switch metric := m.(type) { + case ghostferry.CountMetric: + fmt.Printf("count %s=%d\n", metric.Key, metric.Value) + case ghostferry.GaugeMetric: + fmt.Printf("gauge %s=%g\n", metric.Key, metric.Value) + case ghostferry.TimerMetric: + fmt.Printf("timer %s=%s\n", metric.Key, metric.Value) + } + } + }() + + metrics.Count("myOwnCustomMetrics", 42, nil, 1.0) + + metrics.StopAndFlush() +} ``` -Emit additional metrics: - -```go -metrics.Count("myOwnCustomMetrics", 42, nil, 1.0) -``` +Metric keys are prefixed with the name passed to `SetGlobalMetrics`, so this +prints `count myApp.myOwnCustomMetrics=42`. `StopAndFlush` closes the sink and +waits for every consumer registered with `AddConsumer` to call `DoneConsumer`. +In a real application, stop everything that emits metrics (including the +Ferry) before calling `StopAndFlush`, because sending to the closed sink +panics. Metrics are sent without blocking: when the sink is full, a metric is +dropped and a warning is logged, so size the channel for your consumer's +throughput. diff --git a/docs/index.md b/docs/index.md index 7bc335f91..d2edbdc2b 100644 --- a/docs/index.md +++ b/docs/index.md @@ -24,6 +24,7 @@ Contents: - [Running `ghostferry-copydb` in production](copydbinprod.md) - [Prerequisites](copydbinprod.md#prerequisites) - [Testing Ghostferry with Production Data](copydbinprod.md#testing-ghostferry-with-production-data) + - [Running from a replica](copydbinprod.md#running-from-a-replica) - [To Verify Or Not To Verify](copydbinprod.md#to-verify-or-not-to-verify) - [Dealing with Errors and Restarting Runs](copydbinprod.md#dealing-with-errors-and-restarting-runs) - [Configuration for `ghostferry-copydb`](copydbinprod.md#configuration-for-ghostferry-copydb) @@ -34,8 +35,9 @@ Contents: - [TargetVerifier](verifiers.md#targetverifier) - [Using Ghostferry in Custom Applications](howtousecustom.md) - [Consuming Ghostferry Metrics](howtousecustom.md#consuming-ghostferry-metrics) +- [Changelog](changelog.md) ## Other resources -- [API Documentations](https://godoc.org/github.com/Shopify/ghostferry) +- [API Documentations](https://pkg.go.dev/github.com/Shopify/ghostferry) (versioned; for the `main` branch, the source in the repository is authoritative) - [**Percona Live Conference Slides + Presenter Notes**](_static/percona-talk.pdf) diff --git a/docs/introduction.md b/docs/introduction.md index 0ff5bfb88..305d70eda 100644 --- a/docs/introduction.md +++ b/docs/introduction.md @@ -4,7 +4,8 @@ Ghostferry is a library that enables you to copy data from one MySQL instance to another with minimal amount of downtime. This is accomplished by tailing -and replaying the binlog while the data is being copied by a separate process. +and replaying the binlog while the existing data is being copied by concurrent +goroutines in the same Ghostferry process. Ghostferry is a library rather than an application. The decision to make it so is because Ghostferry has the capability to selectively filter data to copy. @@ -29,9 +30,13 @@ not feasible (mysqldump) or if the filesystem of the database host is not available (for Percona Xtrabackup), such as in the case of cloud provided database as a service. -The traditional process can only move a single table at minimum. Ghostferry -allows you to use the filtering capability to move rows subject to a custom -constraint. +With backup/restore plus replication, any row-level filtering applied to the +initial copy is not carried over to the replication stream, whose filters work +on whole databases or tables. Ghostferry lets an application supply a custom +`CopyFilter`: its `BuildSelect` restricts the rows read during the bulk copy and +its `ApplicableEvent` decides which streamed binlog changes apply, so the same +application-specific filter covers both the initial copy and the ongoing +changes. Additionally, traditional tools present themselves as a complicated process that require a lot of manual intervention from a reasonably experienced diff --git a/docs/technicaloverview.md b/docs/technicaloverview.md index 4d925c77e..efb253ff7 100644 --- a/docs/technicaloverview.md +++ b/docs/technicaloverview.md @@ -25,29 +25,43 @@ database instead. To gain a better understanding of the overall process, let's take a look how Ghostferry works: -1. Ghostferry begins to pull binlog events from the source database, applying - the entries that are applicable to the target. This continues in the - background. -2. Ghostferry SELECTs data from the source database and INSERTs them to the - target database. -3. Ghostferry finishes copying all data from the source and target database. - The binlog apply operation of (1) continues in the background. -4. Ghostferry waits until the binlog apply is close to caught up to the latest - available position on the source database. This is done so we don't initiate - the cutover process when there is a large backlog of binlog entries to be - applied to the target, thereby reducing the downtime required. -5. Outside of Ghostferry: you should allow no more writes to the source - database via either a read_only flag (for whole database copies) or some - sort of application level lock (for partial database copies). -6. Instruct Ghostferry to enter the cutover phase. This essentially tells - Ghostferry to stop tailing the binlog after catching up to the latest master - position. Once Ghostferry does this, it terminates. This step can be done - via the web UI or via a method call. -7. Outside of Ghostferry: you should change the application that uses the - source database to use the target database. You should also enable writes on - the target database if it was previously read only somehow. - -This process has some downtime between step 5 and step 7. The window of +1. `Ferry.Start` records the source's current binlog coordinates (and, unless + target verification is disabled, the target's) before any rows are read, so + no change made during the copy is missed. +2. `Ferry.Run` starts the background tasks: the binlog streamer pulls events + from the source from the recorded coordinates and applies those applicable + to the target, while the data iterator SELECTs rows from the source and + INSERTs them into the target, table by table. +3. Ghostferry finishes copying all data from the source to the target. The + binlog apply operation of (2) continues in the background. +4. `Ferry.Run` waits until cutover is allowed (`AutomaticCutover`), runs the + selected verifier's `VerifyBeforeCutover`, if any, and then notifies the + application that the row copy is complete (`WaitUntilRowCopyIsComplete` + returns) while binlog streaming continues. +5. The application waits until the binlog apply is close to caught up to the + latest available position on the source database + (`WaitUntilBinlogStreamerCatchesUp`), so that cutover does not start with + a large backlog of binlog entries, thereby reducing the downtime required. + copydb then calls the `CutoverLock` callback, if configured. +6. Writes to the copied dataset on the source must now be stopped, via either + a read_only flag (for whole database copies) or some sort of application + level lock (for partial database copies), with in-flight transactions + finished. The application then calls `FlushBinlogAndStopStreaming`: + Ghostferry records the source's current binlog position, applies all events + up to it and stops, and `Ferry.Run` returns. copydb runs steps 4 to 6 + without pausing once Allow Automatic Cutover is clicked in the web UI, so + with copydb the writes must already be stopped before clicking it. +7. The application stops the target verifier (`StopTargetVerifier`), runs the + final verification (`VerifyDuringCutover`) if a verifier is used, and only + then points the application at the target database and enables writes on + it. copydb calls `StopTargetVerifier` and then the `CutoverUnlock` callback + (`EndCutover`) automatically, but does **not** call `VerifyDuringCutover`: + the operator runs it with Run Verification in the web UI. The control + server and any other application components keep running after + `Ferry.Run` returns; returning does not mean that the final verification + has been done. + +This process has some downtime between step 6 and step 7. The window of downtime is proportional to how fast these steps can be done. In most cases this should be on the order of seconds to minutes. @@ -63,42 +77,84 @@ There are several auxiliary components to the system: the throttlers, the verifiers, the control server. These components are optional to Ghostferry runs. -The overall, simplified architecture of Ghostferry can be summarized with the -figure below. It shows the basic flow of all the background tasks, along with -how each task is spawned (starting from `Ferry.Run`). Arrows pointing towards -outside of an encapsulating box indicate the task will exit. The red arrows -with "Error action" indicates an error has occurred and the error is sent to -the `ErrorHandler`, at which point the ErrorHandler flow takes over. +The main components, all running as goroutines of one process, are: -![Ghostferry architecture](_static/ghostferry-architecture.png) +| Component | Role | +|---|---| +| `Ferry` | Initializes the components, coordinates the lifecycle and overall state, and reports fatal errors to the `ErrorHandler`. | +| `DataIterator` → `Cursor` → `BatchWriter` | Copies tables concurrently (one table per worker goroutine), reading each table in pagination-key order in batches and writing each batch to the target; with the Inline verifier, each batch is checked as it is written. | +| Source `BinlogStreamer` → `BinlogWriter` | Streams the source's binlog from the recorded start position and applies applicable changes to the target, until the stop position recorded at cutover is reached. | +| `InlineVerifier` | Re-verifies the pagination keys of rows changed by streamed binlog events (only when the Inline verifier is selected). | +| Target `BinlogStreamer` → `TargetVerifier` | Streams the target's binlog and fails the run on row changes to copied tables that do not carry Ghostferry's expected SQL annotation, i.e. unexpected writers (unless `SkipTargetVerification` is set). | +| `ControlServer` | Web UI and HTTP endpoints exposing status and actions such as pause, cutover and verification. | You can see an example of an application built with Ghostferry in the `copydb` package. ## Limitations -- Right now, Ghostferry can only be used on tables with auto incrementing, - numeric, and unique primary keys. - - - An error will be emitted during the beginning of the run if such a primary - key is not detected. - - In the near future, we will extend support to arbitrary primary key types. - - To work around these restrictions, you can use mysqldump to dump and restore - the table during the cutover. - -- Ghostferry can only be used on a source database with FULL RBR. - - - An error will be emitted during the beginning of the run if FULL RBR is - An error will be emitted during the beginning of the run if FULL RBR is not enabled on the source database. +- Each table is paginated by **one column with unique, non-NULL values**. It + does not need to be an auto-incrementing primary key. + + - Supported column types are integers and binary-comparable strings: + `BINARY`/`VARBINARY` (for example `BINARY(16)` UUIDs) and `CHAR`/`VARCHAR` + with a binary collation such as `utf8mb4_bin`. Other types and non-binary + collations fail schema loading. + - Numeric pagination keys must be positive integers: the cursor starts at + zero and selects values greater than the last key, so zero and negative + values are not supported. Likewise, binary pagination starts from the + empty value, so empty string/binary keys are not supported. Ghostferry + does not validate these boundary values. + - The column is selected in this order: + `CascadingPaginationColumnConfig.PerTable[database][table]`, otherwise the + primary key if it consists of a single column, otherwise + `CascadingPaginationColumnConfig.FallbackColumn`. The fallback applies only + when there is no single-column primary key (including tables with a + composite primary key), not when a single-column primary key has an + unsupported type or collation. A selected column that does not exist or + has an unsupported type or collation fails schema loading. + - Tables with a composite primary key can be copied by configuring one + separate unique column; pagination by multiple columns is not + implemented. You must guarantee that the configured column is unique + (preferably with a UNIQUE index): Ghostferry does not check this, and + duplicate values can cause rows to be skipped at batch boundaries. + + Configuration fragment (not a complete configuration): + + ```json + "CascadingPaginationColumnConfig": { + "PerTable": { + "abc": { + "table1": "id" + } + }, + "FallbackColumn": "id" + } + ``` + +- Ghostferry can only be used on a source database with FULL row-based + replication. + + - The source must have binary logging enabled with `binlog_format=ROW` and + `binlog_row_image=FULL`; an error will be emitted during initialization + otherwise. With target verification enabled (the default), the source must + also have `binlog_rows_query_log_events=ON`, and the target needs binary + logging with `binlog_rows_query_log_events=ON` as well. - Without FULL RBR, the integrity of the data cannot be guaranteed. -- Ghostferry does not support tables with foreign key constraints. +- Tables with foreign key constraints are rejected by default. - For tables with foreign key constraints, the constraints should be removed before performing the data migration. + - `SkipForeignKeyConstraintsCheck: true` bypasses the check but does not + make the migration correct: rows are copied and changes applied without + regard to the constraints. copydb's `TablesToBeCreatedFirst` only orders + table creation on the target. ## Algorithm Correctness -The overall algorithm of Ghostferry is specified in a TLA+ specification and -validated via TLC. The algorithm can be seen in the `tlaplus` directory in the -source tree. +The high-level copy algorithm is described by a simplified TLA+ model in the +`tlaplus` directory of the source tree, with a TLC model configuration in +`tlaplus/ghostferry.toolbox`. The model is small and finite and makes the +simplifying assumptions stated at the top of `tlaplus/ghostferry.tla`. Checking +it with TLC is not a proof that the current Go implementation is correct. diff --git a/docs/tutorialcopydb.md b/docs/tutorialcopydb.md index 17d04dcf4..1f09f4d1e 100644 --- a/docs/tutorialcopydb.md +++ b/docs/tutorialcopydb.md @@ -12,25 +12,37 @@ be found in [Running `ghostferry-copydb` in production](copydbinprod.md). ## Setup and Seed MySQL -In this tutorial, we will be using two test databases that we setup locally and -we will not consider the application. With git, clone the Ghostferry repository -and create the test MySQL instances: +In this tutorial, we will be using two disposable test databases that we set up +locally and we will not consider the application. You need Git, Make, a MySQL +client, Go 1.26.2 (the `go` directive in `go.mod` is authoritative) and Docker +or Podman. Clone the Ghostferry repository and start the MySQL 8.0 test +instances: ```console $ git clone https://github.com/Shopify/ghostferry.git $ cd ghostferry -$ docker-compose up -d mysql-1 mysql-2 +$ docker compose -f docker-compose_8.0.yml up -d mysql-1 mysql-2 ``` -Users without docker-compose can either install it on their machine or manually -setup two localhost MySQL instances available at port 29291 and 29292 with FULL -image row based replication. +With Podman, use `podman-compose -f docker-compose_8.0.yml up -d mysql-1 mysql-2` +instead. These servers listen on ports 29291 and 29292 and have a `root` +account without a password. They are throwaway local test servers, not an +example of production credentials. -Confirm that you can access both MySQL instances with the MySQL console: +Without Docker or Podman, you can set up two MySQL instances on localhost ports +29291 and 29292 yourself. Both need binary logging enabled with +`binlog_format=ROW`, `binlog_row_image=FULL` and +`binlog_rows_query_log_events=ON`. Ghostferry checks the source's settings +during initialization; the target needs `binlog_rows_query_log_events=ON` +because Ghostferry monitors the target's binary log for unexpected writes (see +[TargetVerifier](verifiers.md#targetverifier)). A dry run does not check every +target setting. + +Wait until both MySQL instances accept connections from the MySQL console: ```console -# mysql --protocol=tcp -u root -P 29291 -# mysql --protocol=tcp -u root -P 29292 +$ mysql --protocol=tcp -u root -P 29291 -e 'SELECT 1' +$ mysql --protocol=tcp -u root -P 29292 -e 'SELECT 1' ``` We will be moving data from the 29291 server to the 29292 server. To do this, @@ -50,7 +62,7 @@ rm /tmp/n1create.sql ``` This created two tables under the database `abc`. We will be moving -`table1` to 29292 while not copying 29291. +`table1` to 29292 while not copying `abc.table2`. ## (Mirrors Production) Create Ghostferry Users @@ -75,11 +87,14 @@ On the target server, the minimum permissions required are: ```console mysql> CREATE USER 'ghostferry'@'%' IDENTIFIED BY 'ghostferry'; mysql> GRANT INSERT, UPDATE, DELETE, CREATE, SELECT ON *.* TO 'ghostferry'@'%'; +mysql> GRANT REPLICATION SLAVE, REPLICATION CLIENT ON *.* TO 'ghostferry'@'%'; ``` We grant permission to all databases because we assume that the `abc` database does not exist on the target and Ghostferry will create it -automatically. +automatically. The replication privileges on the target are needed because, by +default, Ghostferry streams the target's binary log to detect writes to the +target that it did not make itself. ## (Mirrors Production) Install ghostferry-copydb @@ -89,13 +104,23 @@ this server over its network so make sure the production server is appropriately picked. For the present tutorial, Ghostferry will simply live on the same machine. -To download the latest binaries, you currently have to compile copydb with -Go 1.9 via `make copydb` after cloning the repository. +Build ghostferry-copydb from the repository root: + +```console +$ export GOPATH="$(go env GOPATH)" +$ export PATH="${GOPATH%%:*}/bin:$PATH" +$ make copydb +``` -For testing purposes, you can also use [this unofficial PPA](https://launchpad.net/~shuhao/+archive/ubuntu/ghostferry-unofficial) (see -[this PR](https://github.com/Shopify/ghostferry/pull/15) as well) to obtain a -version of ghostferry-copydb. Note the unofficial PPA for ghsotferry-copydb is -not supported and you should not use it in production. +This installs `ghostferry-copydb` into the `bin` directory of the first +`GOPATH` entry. Run it from the repository root throughout this tutorial: the +web UI templates are loaded from `webui/` below +`ControlServerConfig.WebBasedir`, which defaults to the current directory. +Debian packages instead compile in the base directory `/usr/share/ghostferry` +and install `webui/` beneath it (the base directory is always the parent of +`webui/`). Packaged builds are published on the project's +[GitHub Releases](https://github.com/Shopify/ghostferry/releases) page; most of +them are prereleases built from `main` or canary tags. ## (Mirrors Production) Setup Ghostferry Run Configuration @@ -135,11 +160,15 @@ which should look like the following: "Blacklist": ["table2"] }, - "VerifierType": "ChecksumTable" + "VerifierType": "ChecksumTable", + + "ControlServerConfig": { + "ServerBindAddr": "127.0.0.1:8000" + } } ``` -Save this file to a file called `examplerun.json`. +Save this file to a file called `examplerun.json` in the repository root. Note that in the example above, the Collation and charsets are set. If you setup your own MySQL instances, you might need to change these values. We are @@ -147,10 +176,15 @@ also using the `Whitelist` and `Blacklist` to ensure that we only copy `abc.table1` from the source to the target. For more information about this configuration file, see [Running `ghostferry-copydb` in production](copydbinprod.md). -Lastly, we have enabled verification to be available to use during the run. -Specifically, we enabled the ChecksumTable verifier as the amount of data -copied will be small. For more information about the verifiers, see -[Verifiers](verifiers.md). +`ControlServerConfig.ServerBindAddr` limits the web UI to the local machine. +When it is not configured, the UI listens on `0.0.0.0:8000`, which is reachable +from other hosts on the network. + +Lastly, we have selected a data verifier to be available to use during the +run. Specifically, we selected the ChecksumTable verifier as the amount of data +copied will be small. Independently of that choice, Ghostferry monitors the +target for unexpected writes by default. For more information about the +verifiers, see [Verifiers](verifiers.md). ## (Mirrors Production) Validate Ghostferry Configuration @@ -165,72 +199,72 @@ $ ghostferry-copydb -dryrun -verbose examplerun.json ``` The verbose flag gives slightly more debug information in case there are any -issues. In this case, there should not be any issues as we setup the database -according to the tutorial and the output should be something like this -(simplified for readibility in the tutorial): - -```text -[...] -INFO[0000] connecting to the source database dsn="ghostferry:@[...]" tag=ferry -INFO[0000] connecting to the target database dsn="ghostferry:@[...]" tag=ferry -[...] -INFO[0000] found binlog position, starting synchronization file=[...] pos=[...] tag=binlog_streamer -[...] -DEBU[0000] loading tables from database database=abc tag=table_schema_cache -DEBU[0000] fetching table schema database=abc table=table1 tag=table_schema_cache -DEBU[0000] fetching table schema database=abc table=table2 tag=table_schema_cache -DEBU[0000] caching table schema database=abc table=table1 tag=table_schema_cache -INFO[0000] table schemas cached tables="[abc.table1]" tag=table_schema_cache -exiting due to dryrun -``` +issues. The exact log wording and fields depend on the configured logging +backend, but a successful dry run of this tutorial shows: + +- a `table schemas cached` log entry listing only `abc.table1`; +- binlog streaming starting for both the source and the target connection; +- `exiting due to dryrun` as the last line on stdout. -Note the last INFO line shows which tables will be moved as we cache their -schemas in the memory. If there is a table you want to move and it does not -show up there, it means the whitelist/blacklist configuration is incorrect. +No tables or rows are copied during a dry run. If a table you want to move is +not in the cached list, the whitelist/blacklist configuration is incorrect. ## (Mirrors Production) Starting Ghostferry Run To start the ghostferry run, simply perform the same command as before except without the dryrun flag. You can also turn off the verbose flag, although it -may be good practise to leave it on and redirect stdout to a file so the move -can be audited at a later time. We will do this here for good practise: +may be good practise to leave it on and write the logs to a file so the move +can be audited at a later time. Run it in its own terminal and use other +terminals for the MySQL and web UI steps below: ```console -$ ghostferry-copydb -verbose examplerun.json 2&>examplerun.log +$ ghostferry-copydb -verbose examplerun.json >examplerun.log 2>&1 ``` +This command merges stdout and stderr into one log file. If you want to be able +to resume an interrupted run, stdout must instead be captured separately from +the logs, as described in +[Interrupt and resuming `ghostferry-copydb`](copydbinterruptresume.md). + To confirm that Ghostferry indeed copies changes to the source table, we can -manually insert a row into `abc.table1` during the run +manually insert a row into `abc.table1` during the run, while the UI shows it +waiting for cutover: ```console -# mysql --protocol=tcp -u root -P 29291 +$ mysql --protocol=tcp -u root -P 29291 mysql> INSERT INTO abc.table1 (id, data) VALUES (351, "helloworld"); ``` ## (Mirrors Production) Monitoring Ghostferry Run via Web UI -Once the run starts, a built-in webserver is started at port 8000 by default. -This can be changed in the configuration json. Simply browse to - to view this server and in there you should find controls -to: - -- Pause/Unpause: allows you to pause/unpause the data copy and binlog streaming - process. -- Allow automatic cutover: You should only press this button after you set the - source database to read only. In its current implementation, it will simply - allow ghostferry-copydb to finish all its processes in a correct manner, - assuming that there are no more writes to the source database and all pending - writes have been flushed to the binlog. In a future implementation, we may - allow external scripts (configured via the json configuration) to be - automatically executed with the push of this button so you can perform - operations you need to perform during cutover. -- Run Verification: This button is only available during the Wait-For-Cutover - and Done phase of the move. It will run the ChecksumTable verifier we - specified earlier ensure the data are identical on the source and target. You - should only run this while the source is read only and when the target is not - yet written to. - -The page will refresh itself every 60 seconds. +Once the run starts, the built-in web server listens on the configured +`ControlServerConfig.ServerBindAddr`. Browse to to view +it; there you should find controls to: + +- Pause/Unpause: pauses/resumes table iteration and the application of binlog + events to the target. It does not stop writes to the source, and it does not + immediately stop every binlog streamer. +- Allow Automatic Cutover: lets ghostferry-copydb proceed with cutover once + the row copy is complete and the binlog streamer has nearly caught up. It does + not stop application writes itself: you must stop writes to the source before + pressing it. ghostferry-copydb then records the source's current binlog + position, applies the remaining events up to it and stops streaming. The + configuration fields `CutoverLock` and `CutoverUnlock` can name HTTP + callbacks that copydb calls at the start and at the end of this procedure, and + `ControlServerConfig.CustomScripts` adds separate buttons that run scripts on + demand. `CutoverUnlock` is called before any operator-triggered final + verification, so it does not mean that the data has been verified. +- Run Verification: shown when the run is neither starting nor copying and no + verification is in progress. It runs the ChecksumTable verifier we specified + earlier to compare the copied tables on the source and target. Only run it + once the source binlog streaming has finished (after cutover), while the + source is still read only and before anything else writes to the target. + (The Inline verifier's final verification can only be run once and rejects + any source binlog events arriving after it started.) + +While the run is not done, the page refreshes itself every 60 seconds. Once the +run is done it no longer refreshes; use the Manual Refresh link to see +verification progress. For this tutorial, the run should be very short so thus you might miss most of the copying states. Take a look around and refresh a couple times to get @@ -239,41 +273,58 @@ familiar with the UI. ## (Mirrors Production) Perform Cutover In the default configuration, cutover is triggered manually. During cutover, -you must stop writes to the data on the source database. For the purpose of -this tutorial, we will set the source database to read only. Even though we -have no applications writing to the source in this case, let's do it anyway so -we get into the habit of thinking of this step: +you must stop writes to the data on the source database: the application must +stop its writers and let in-flight transactions finish. For the purpose of this +tutorial, we lock the source and set it to read only. Even though we have no +applications writing to the source in this case, let's do it anyway so we get +into the habit of thinking of this step. + +Open a dedicated interactive session and keep it open until the final +verification below has succeeded; the lock is released when the session ends: ```console -# mysql --protocol=tcp -u root -P 29291 -mysql> FLUSH TABLES WITH READ LOCK; -- Ensure all writes are done -mysql> SET GLOBAL read_only = ON; -- Sets the database to read only -mysql> FLUSH BINARY LOGS -- Ensure all writes are record in binlog +$ mysql --protocol=tcp -u root -P 29291 +mysql> FLUSH TABLES WITH READ LOCK; +mysql> SET GLOBAL read_only = ON; ``` -The last step `FLUSH BINARY LOGS` is not necessarily required if you run your -MySQL server with `sync_binlog=1`. If you're running Ghostferry from a source -that is a replica, you need to also turn on the option `RunFerryFromReplica` -in the config json as well as other options. See - for more -details. +See the [MySQL `FLUSH TABLES WITH READ LOCK` +documentation](https://dev.mysql.com/doc/refman/8.0/en/flush.html#flush-tables-with-read-lock) +for what the lock does and does not block. Ghostferry does not need a +`FLUSH BINARY LOGS`: that statement only rotates the binary log. When cutover +starts, Ghostferry reads the source's current binlog position and applies all +events up to it. In production, account for privileged writers, replication +and the application's own write paths rather than relying on this tutorial's +procedure alone. + +If you run Ghostferry from a source that is a replica, you need to set +`RunFerryFromReplica` together with `SourceReplicationMaster` and +`ReplicatedMasterPositionQuery` in the config json. See +[Running `ghostferry-copydb` in production](copydbinprod.md) and + for more +details (the API documentation is versioned; the source in this repository is +authoritative for `main`). We can then go back to the web ui and click the Allow Automatic Cutover button. In a second or two the ghostferry binlog streaming process should stop. Refresh -the page until you see the state to be DONE. +the page until you see the state to be done. Done means that copying and +binlog streaming have completed; it does not mean that the final verification +has passed. The process and its web UI keep running. ## (Mirrors Production) Verify Source and Target Data are Identical -At this point, the data on the source and target should be identical. To -confirm this is the case, click the Run Verification button in the web ui to -perform the verification in the background. Refresh the page a couple of times -until it tells you the verification was successful. +ghostferry-copydb does not run the final verification automatically. With the +source still locked, click the Run Verification button in the web ui to perform +the verification in the background. Use Manual Refresh until Verified Correct +shows `true` and no error is reported. Only after that should applications be +allowed to write to the target. Verified Correct covers the tables and columns +the selected verifier compares; see [Verifiers](verifiers.md) for its limits. Additionally, since we manually inserted a row earlier, we should be able to find it via: ```console -# mysql --protocol=tcp -u root -P 29292 +$ mysql --protocol=tcp -u root -P 29292 mysql> SELECT * FROM abc.table1 WHERE id = 351; ``` @@ -284,6 +335,17 @@ Ghostferry will no longer propagate data from 29291 to 29292. In a production situation, you can now notify all applications using the source database to use the target database. +Because the servers are disposable local fixtures, restore the source in the +session that still holds the lock: + +```console +mysql> UNLOCK TABLES; +mysql> SET GLOBAL read_only = OFF; +``` + +Do not copy this step into a production cutover: there, the old source should +stay closed to application writes once they have moved to the target. + The control server UI will stay up indefinitely. To stop it, simply press CTRL+C to interrupt the ghostferry-copydb process. diff --git a/docs/verifiers.md b/docs/verifiers.md index b0eef7044..18ac9617a 100644 --- a/docs/verifiers.md +++ b/docs/verifiers.md @@ -1,9 +1,21 @@ # Verifiers Verifiers in Ghostferry are designed to ensure that Ghostferry did not -corrupt/miss data. There are three different verifiers: the -`ChecksumTableVerifier`, the `InlineVerifier`, and the `TargetVerifier`. A comparison of the -`ChecksumTableVerifier` and `InlineVerifier` are given below: +corrupt/miss data. There are two independent mechanisms: + +- A **data verifier**, selected with `VerifierType` in the embedded + `ghostferry.Config`: `"ChecksumTable"`, `"Inline"`, the deprecated + `"Iterative"`, or `"NoVerification"`. Leaving `VerifierType` empty means no + data verifier in copydb; in library code, an empty `VerifierType` lets you + supply your own `Ferry.Verifier` instead. +- The **`TargetVerifier`**, which monitors the target's binlog for writes that + did not come from Ghostferry. It is enabled by default + (`SkipTargetVerification: false`) whichever data verifier is chosen, + including `NoVerification`. It does not compare row contents and is not a + substitute for a final data verification. + +A comparison of the `ChecksumTableVerifier` and `InlineVerifier` data +verifiers is given below: | | ChecksumTableVerifier | InlineVerifier | |---|---|---| @@ -21,15 +33,20 @@ corrupt/miss data. There are three different verifiers: the [^2]: Increase in copy time does not increase downtime. Downtime occurs only in cutover. -If you want verification, you should try with the `ChecksumTableVerifier` -first if you're copying whole tables at a time. If that takes too long, you can -try using the `InlineVerifier`. Alternatively, you can verify in a staging -run and not verify during the production run (see -[Running `ghostferry-copydb` in production](copydbinprod.md)). +`ChecksumTable` is a simple choice for small whole-table copies such as the +[tutorial](tutorialcopydb.md), because it scans every copied table during +cutover. `Inline` is the non-deprecated incremental option for larger datasets +or partial copies. A successful verification in a rehearsal does not verify +the data of a later run; see +[Running `ghostferry-copydb` in production](copydbinprod.md). Note that the `InlineVerifier` on its own may potentially miss some -cases, and using it with the `TargetVerifier` is recommended if these -cases are possible. +cases, and keeping the `TargetVerifier` enabled is recommended if these +cases are possible. In the table below, "Yes" means the condition is detected +within the scope of the selected verifier: the copied tables, and for the +Inline verifier the compared columns (columns configured in +`IgnoredColumnsForVerification` are skipped, and columns listed in +`CompressedColumnsForVerification` are compared after decompression). | Conditions | ChecksumTable | Inline | Inline + Target | |---|---|---|---| @@ -84,9 +101,9 @@ IterativeVerifier verifies the source and target in a couple of steps: 1. If they are the same: the verification for that row is complete. 2. If they are not the same: the verification fails. -5. If no verification failure occurs, the source and the target are identical. - If verification failure does occur (4b), then the source and target are not - identical. +5. If no verification failure occurs, the compared rows of the source and the + target are identical within the scope of the verifier. If verification + failure does occur (4b), then the source and target are not identical. A proof of concept TLA+ verification of this algorithm is done in . @@ -107,54 +124,84 @@ With regards to the `DataIterator` and `BatchWriter`: 2. The fingerprint, gathered from the `MD5(...)` of the query above is stored on the `RowBatch` to be used in the next verification step. -3. The `BatchWriter` then attempts to write the `RowBatch`, but instead of inserting - it directly, the following process is taken: +3. The `BatchWriter` then writes the `RowBatch` as follows: - 1. A transaction is opened. + 1. A transaction is opened on the target. 2. The data contained in the `RowBatch` is inserted. - 3. The PK and fingerprint is then `SELECT`ed from the Target - as `SELECT pk, MD5(....) FROM ...`. - 4. The fingerprint (`MD5`) is then checked against the fingerprint currently - stored on the `RowBatch`. - - The process in step 3 above is retried (with a limit) if there happens to be - a failure or mismatch, and will fail the run if they are not verified within - the retry limits. + 3. The pagination key and fingerprint of these rows are then `SELECT`ed + from the target in the same transaction. + 4. The target fingerprints are compared with the source fingerprints stored + on the `RowBatch`. The pagination keys of mismatched rows are added to + the `reverifyStore` to be verified again later. + 5. The transaction is committed. + + Query and write failures are retried (with a limit) and fail the run if + the retry limit is exceeded. A mismatch alone does not abort the copy: it + is enqueued for reverification. The exception is when + `EnforceInlineVerification` is set on the `BatchWriter` (used for + standalone copies without binlog streaming, such as + `Ferry.RunStandaloneDataCopy`), where a mismatch fails the batch. With regards to the BinlogStreamer: -1. As DMLs are observed by the `BinlogStreamer`, the PKs of the events are placed into - a `reverifyStore` to be periodically verified for correctness. +1. As DMLs are observed by the `BinlogStreamer`, the pagination keys of the + changed rows are placed into the `reverifyStore` to be periodically verified + for correctness, every `InlineVerifierConfig.VerifyBinlogEventsInterval` + (default `"1s"`). + +2. This continues to happen in the background until cutover is allowed. -2. This continues to happen in the background throughout the process of the Run. +3. If a row is found not to match, its pagination key is added back into the + `reverifyStore` to be verified again. -3. If a PK is found not to match, it is added back into the reverifyStore to be verified - again. +4. `VerifyBeforeCutover` reverifies the `reverifyStore` in at most 30 passes, + stopping early once at most 1000 rows remain queued or a pass no longer + shrinks the queue. If `InlineVerifierConfig.MaxExpectedDowntime` is set + (non-empty and non-zero) and the last pass took longer, the run fails. This + is an estimate, not a hard guarantee on downtime. -4. When `VerifyBeforeCutover` starts, the InlineVerifier will verify enough of the - events in the `reverifyStore` to ensure it has a sufficiently small number of events - that can be successfully verified before cutover. +5. When `VerifyDuringCutover` begins, all of the remaining rows in the + `reverifyStore` are verified. If any mismatch remains, the result has + `DataCorrect: false` and a message listing the mismatched pagination keys. + `VerifyDuringCutover` can only be started once, and any source binlog event + received after it started is an error. -5. When `VerifyDuringCutover` begins, all of the remaining events in the `reverifyStore` - are verified and any mismatches are returned. +`VerifyDuringCutover` must be called after binlog streaming has stopped and +before the target receives application writes. ghostferry-copydb does **not** +call it automatically: the operator must click Run Verification in the web UI +after cutover and check that Verified Correct is `true` and no error is shown +before letting applications write to the target. The copydb state `done` only +means that copying and streaming have finished. Custom applications must call +`VerifyDuringCutover` themselves. ## TargetVerifier -TargetVerifier ensures data on the Target is not corrupted during the move process -and is meant to be used in conjunction with another verifier above. +TargetVerifier detects writes to the copied tables on the target that were not +made by Ghostferry during the move process. It is enabled by default and is +meant to be used in conjunction with one of the data verifiers above; it does +not compare row contents. + +Ghostferry prepends an SQL annotation (`Target.Marginalia`, default +`application:ghostferry`) to its statements on the target. The TargetVerifier +checks for this expected annotation: -It uses a configurable annotation string that is prepended to DMLs that acts as -a verified "signature" of all of Ghostferry's operations on the Target: +1. A BinlogStreamer is created and attached to the Target. This requires the + target to have binary logging with `binlog_rows_query_log_events=ON`, and + the target user to have replication privileges. -1. A BinlogStreamer is created and attached to the Target +2. As this BinlogStreamer receives DML events for the copied tables, it + extracts the annotation from the query event preceding each `RowsEvent`. -2. As this BinlogStreamer receives DML events, it attempts to extract the annotation - from each for each of the `RowsEvents`. +3. If no annotation is found for the DML, or the extracted annotation text does + not match `Target.Marginalia`, an error is returned and the run fails. -3. If an annotation is not found for the DML, or the extracted annotation does not - match the configured annotation of Ghostferry, an error is returned and the process fails. +This detects unexpected writers; it is not cryptographic authentication and +does not protect against a writer that deliberately uses the same annotation. -The TargetVerifier needs to be manually stopped before cutover. If it is not stopped, -it may detect writes from the application (that are not from Ghostferry) and fail the run. -Stopping before cutover also gives the TargetVerifier the opportunity to inspect all -of the DMLs in its `BinlogStreamer` queue to ensure no corruption of the data has occurred. +The TargetVerifier must be stopped (`Ferry.StopTargetVerifier`) after source +binlog processing has finished and before the target is opened to application +writes; otherwise it would fail the run on the application's writes. Stopping +it also lets it process all target binlog events up to the stop point. +ghostferry-copydb does this automatically after the source binlog streaming +stops and before calling `CutoverUnlock`. Custom applications must do the +equivalent themselves. diff --git a/error_handler.go b/error_handler.go index 70dad080b..df88ddaa9 100644 --- a/error_handler.go +++ b/error_handler.go @@ -9,8 +9,10 @@ import ( ) type ErrorHandler interface { - // Usually called from Fatal. When called from Fatal, if this method returns - // true, Fatal should panic, otherwise it should not. + // Reports the error (for example logging it, dumping the state and + // invoking an error callback). It does not decide whether to terminate; + // that is Fatal's responsibility (PanicErrorHandler.Fatal reports the + // error and then panics). ReportError(from string, err error) Fatal(from string, err error) } diff --git a/examples/copydb/conf.json b/examples/copydb/conf.json index b391a68ca..ecf3e7d67 100644 --- a/examples/copydb/conf.json +++ b/examples/copydb/conf.json @@ -29,17 +29,12 @@ "Blacklist": ["schema_migrations"] }, - "ForceIndexForVerification": { - "abc": { - "table1": "forced_index_name" - } - }, - "DumpStateOnSignal": true, "VerifierType": "Inline", - "ControlServer": { + "ControlServerConfig": { + "ServerBindAddr": "127.0.0.1:8000", "CustomScripts": { "Custom Script 1": ["examples/copydb/s1"], "Custom Script 2": ["examples/copydb/s2"] diff --git a/filter.go b/filter.go index 9c367156e..e9a23f1e3 100644 --- a/filter.go +++ b/filter.go @@ -5,7 +5,7 @@ import ( ) // CopyFilter provides an interface for restricting the copying to a subset of -// data. This typically involves adding a WHERE condition in the ConstrainSelect +// data. This typically involves adding a WHERE condition in the BuildSelect // function, and returning false for unwanted rows in ApplicableEvent. type CopyFilter interface { // BuildSelect is used to set up the query used for batch data copying, @@ -18,8 +18,8 @@ type CopyFilter interface { BuildSelect([]string, *TableSchema, PaginationKey, uint64) (sq.SelectBuilder, error) // ApplicableEvent is used to filter events for rows that have been - // filtered in ConstrainSelect. ApplicableEvent should return true if the - // event is for a row that would be selected by ConstrainSelect, and false + // filtered in BuildSelect. ApplicableEvent should return true if the + // event is for a row that would be selected by BuildSelect, and false // otherwise. // Returning an error here will cause the ferry to be aborted. ApplicableEvent(DMLEvent) (bool, error) diff --git a/verifier.go b/verifier.go index aacc6f708..2db8d392e 100644 --- a/verifier.go +++ b/verifier.go @@ -82,8 +82,9 @@ type Verifier interface { // // If the verification has been completed successfully (without errors) and // the data checks out to be "correct", the result will be - // VerificationResult{true, ""}, with error = nil. - // Otherwise, the result will be VerificationResult{false, "message"}, with + // VerificationResult{DataCorrect: true}, with error = nil. + // Otherwise, the result will be + // VerificationResult{DataCorrect: false, Message: "..."}, with // error = nil. // // If the verification is "done" but experienced an error during the check, From b2dd82a04061197e5c1b51c7e1a4db50584bec25 Mon Sep 17 00:00:00 2001 From: Leszek Zalewski Date: Wed, 30 Sep 2026 14:00:20 +0200 Subject: [PATCH 2/3] Make setup for contributors up to date --- .envrc | 3 - .tool-versions | 2 + README.md | 26 ++++++++- gemset.nix | 147 ------------------------------------------------- shell.nix | 21 ------- 5 files changed, 26 insertions(+), 173 deletions(-) delete mode 100644 .envrc create mode 100644 .tool-versions delete mode 100644 gemset.nix delete mode 100644 shell.nix diff --git a/.envrc b/.envrc deleted file mode 100644 index c395fdcd5..000000000 --- a/.envrc +++ /dev/null @@ -1,3 +0,0 @@ -if [ -d /nix ]; then - use_nix -fi diff --git a/.tool-versions b/.tool-versions new file mode 100644 index 000000000..26809ffc3 --- /dev/null +++ b/.tool-versions @@ -0,0 +1,2 @@ +golang 1.26.2 +ruby 3.4.8 diff --git a/README.md b/README.md index 62e036c28..33b3c02a1 100644 --- a/README.md +++ b/README.md @@ -80,8 +80,8 @@ Development Setup unless `CI` is set. - Docker (or Podman with `podman-compose`) for the local MySQL servers. -`shell.nix` is legacy: it still selects Go 1.18 and Ruby 2.7 and is not a -supported setup. +Go and Ruby versions are pinned in `.tool-versions`, which both +[mise](https://mise.jdx.dev/) and [asdf](https://asdf-vm.com/) read. #### For Internal Contributors @@ -89,6 +89,28 @@ supported setup. #### For External Contributors +Install Go and Ruby with mise or asdf from the repository root: + +```sh +mise install # or: asdf install +``` + +Without a version manager, any Go 1.21 or newer also works: because `go.mod` +requires Go 1.26.2, the `go` command downloads and uses that toolchain itself. + +Install the MySQL client and its development libraries (needed by the `mysql2` +gem), for example `brew install mysql-client` on macOS or +`apt install default-mysql-client default-libmysqlclient-dev` on Debian/Ubuntu, +then install the gems: + +```sh +bundle install +``` + +Homebrew's `mysql-client` is keg-only; if `mysql2` cannot find it, run +`bundle config set build.mysql2 --with-mysql-config="$(brew --prefix mysql-client)/bin/mysql_config"` +first. + Start two disposable MySQL 8.0 servers from the repository root: ```sh diff --git a/gemset.nix b/gemset.nix deleted file mode 100644 index 4ca39d11b..000000000 --- a/gemset.nix +++ /dev/null @@ -1,147 +0,0 @@ -{ - ansi = { - groups = ["default"]; - platforms = []; - source = { - remotes = ["https://rubygems.org"]; - sha256 = "14ims9zfal4gs2wpx2m5rd8zsrl2k794d359shkrsgg3fhr2a22l"; - type = "gem"; - }; - version = "1.5.0"; - }; - builder = { - groups = ["default"]; - platforms = []; - source = { - remotes = ["https://rubygems.org"]; - sha256 = "045wzckxpwcqzrjr353cxnyaxgf0qg22jh00dcx7z38cys5g1jlr"; - type = "gem"; - }; - version = "3.2.4"; - }; - byebug = { - groups = ["default"]; - platforms = []; - source = { - remotes = ["https://rubygems.org"]; - sha256 = "0nx3yjf4xzdgb8jkmk2344081gqr22pgjqnmjg2q64mj5d6r9194"; - type = "gem"; - }; - version = "11.1.3"; - }; - coderay = { - groups = ["default" "development"]; - platforms = []; - source = { - remotes = ["https://rubygems.org"]; - sha256 = "0jvxqxzply1lwp7ysn94zjhh57vc14mcshw1ygw14ib8lhc00lyw"; - type = "gem"; - }; - version = "1.1.3"; - }; - method_source = { - groups = ["default"]; - platforms = []; - source = { - remotes = ["https://rubygems.org"]; - sha256 = "1pnyh44qycnf9mzi1j6fywd5fkskv3x7nmsqrrws0rjn5dd4ayfp"; - type = "gem"; - }; - version = "1.0.0"; - }; - minitest = { - groups = ["test"]; - platforms = []; - source = { - remotes = ["https://rubygems.org"]; - sha256 = "19z7wkhg59y8abginfrm2wzplz7py3va8fyngiigngqvsws6cwgl"; - type = "gem"; - }; - version = "5.14.4"; - }; - minitest-fail-fast = { - dependencies = ["minitest"]; - groups = ["default"]; - platforms = []; - source = { - remotes = ["https://rubygems.org"]; - sha256 = "0kgxx7v1wyk1zaim41zim3z4s9nx1ybani2097v39h1fqn2mzdr5"; - type = "gem"; - }; - version = "0.1.0"; - }; - minitest-hooks = { - dependencies = ["minitest"]; - groups = ["default"]; - platforms = []; - source = { - remotes = ["https://rubygems.org"]; - sha256 = "05z8r6sw3fz4s44fs1150ndlcmcy82vlxmhps5nncg8vk59k3gmf"; - type = "gem"; - }; - version = "1.5.0"; - }; - minitest-reporters = { - dependencies = ["ansi" "builder" "minitest" "ruby-progressbar"]; - groups = ["test"]; - platforms = []; - source = { - remotes = ["https://rubygems.org"]; - sha256 = "0pj98s2rza8c38crh35lcrv59w7qr13g09swfh5aqabl3552xxr6"; - type = "gem"; - }; - version = "1.4.3"; - }; - mysql2 = { - groups = ["test"]; - platforms = []; - source = { - remotes = ["https://rubygems.org"]; - sha256 = "0d14pcy5m4hjig0zdxnl9in5f4izszc7v9zcczf2gyi5kiyxk8jw"; - type = "gem"; - }; - version = "0.5.3"; - }; - pry = { - dependencies = ["coderay" "method_source"]; - groups = ["default"]; - platforms = []; - source = { - remotes = ["https://rubygems.org"]; - sha256 = "0iyw4q4an2wmk8v5rn2ghfy2jaz9vmw2nk8415nnpx2s866934qk"; - type = "gem"; - }; - version = "0.13.1"; - }; - pry-byebug = { - dependencies = ["byebug" "pry"]; - groups = ["default"]; - platforms = []; - source = { - remotes = ["https://rubygems.org"]; - sha256 = "096y5vmzpyy4x9h4ky4cs4y7d19vdq9vbwwrqafbh5gagzwhifiv"; - type = "gem"; - }; - version = "3.9.0"; - }; - ruby-progressbar = { - groups = ["default" "test"]; - platforms = []; - source = { - remotes = ["https://rubygems.org"]; - sha256 = "02nmaw7yx9kl7rbaan5pl8x5nn0y4j5954mzrkzi9i3dhsrps4nc"; - type = "gem"; - }; - version = "1.11.0"; - }; - tqdm = { - groups = ["default"]; - platforms = []; - source = { - remotes = ["https://rubygems.org"]; - sha256 = "1xmc2y990s0k3yydijyqifkgirzhlicb0p7b12habcksfs0h4rna"; - type = "gem"; - }; - version = "0.3.0"; - }; -} diff --git a/shell.nix b/shell.nix deleted file mode 100644 index ff7858d6d..000000000 --- a/shell.nix +++ /dev/null @@ -1,21 +0,0 @@ -with (import {}); -let - ruby = ruby_2_7; - env = bundlerEnv { - name = "ghostferry-bundler-env"; - ruby = ruby; - gemfile = ./Gemfile; - lockfile = ./Gemfile.lock; - gemset = ./gemset.nix; - # https://github.com/NixOS/nixpkgs/issues/83442#issuecomment-768669544 - copyGemFiles = true; - }; -in stdenv.mkDerivation { - name = "ghostferry"; - buildInputs = [ - env - ruby - go_1_18 - mysql57 - ]; -} From 7de1d2175a7a45f75a45a1bcfa1370d74841f1c6 Mon Sep 17 00:00:00 2001 From: Leszek Zalewski Date: Wed, 30 Sep 2026 14:09:41 +0200 Subject: [PATCH 3/3] Pull go version from go.mod --- .github/workflows/release.yml | 2 +- .github/workflows/tests.yml | 8 ++++---- 2 files changed, 5 insertions(+), 5 deletions(-) diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml index b05ebc8c7..c06d8bced 100644 --- a/.github/workflows/release.yml +++ b/.github/workflows/release.yml @@ -19,7 +19,7 @@ jobs: - name: Setup Go uses: actions/setup-go@v6.4.0 with: - go-version: "1.26.2" + go-version-file: go.mod - name: Building Ghostferry run: .github/workflows/build-deb.sh diff --git a/.github/workflows/tests.yml b/.github/workflows/tests.yml index b6a94e625..187c85513 100644 --- a/.github/workflows/tests.yml +++ b/.github/workflows/tests.yml @@ -32,7 +32,7 @@ jobs: - uses: actions/checkout@v6.0.2 - uses: actions/setup-go@v6.4.0 with: - go-version: "1.26.2" + go-version-file: go.mod - name: Starting up MySQL run: .github/workflows/start-mysql.sh @@ -57,7 +57,7 @@ jobs: - uses: actions/checkout@v6.0.2 - uses: actions/setup-go@v6.4.0 with: - go-version: "1.26.2" + go-version-file: go.mod - name: Starting up MySQL run: .github/workflows/start-mysql.sh @@ -88,7 +88,7 @@ jobs: - uses: actions/checkout@v6.0.2 - uses: actions/setup-go@v6.4.0 with: - go-version: "1.26.2" + go-version-file: go.mod - uses: ruby/setup-ruby@v1 with: bundler-cache: true @@ -108,7 +108,7 @@ jobs: - uses: actions/checkout@v6.0.2 - uses: actions/setup-go@v6.4.0 with: - go-version: "1.26.2" + go-version-file: go.mod - name: Building Ghostferry run: .github/workflows/build-deb.sh --tagged-only