From 7e7f4160c1c2c47276609b20a7e8f62f6200597b Mon Sep 17 00:00:00 2001 From: James Opstad <13586373+jamesopstad@users.noreply.github.com> Date: Mon, 3 Mar 2025 15:42:06 +0000 Subject: [PATCH 01/34] Initial Vite plugin docs --- src/content/docs/workers/vite-plugin/api.mdx | 69 +++++ .../vite-plugin/cloudflare-environments.mdx | 100 +++++++ .../docs/workers/vite-plugin/get-started.mdx | 73 +++++ .../docs/workers/vite-plugin/index.mdx | 20 ++ .../migrating-from-wrangler-dev.mdx | 23 ++ .../docs/workers/vite-plugin/secrets.mdx | 16 ++ .../docs/workers/vite-plugin/tutorial.mdx | 252 ++++++++++++++++++ 7 files changed, 553 insertions(+) create mode 100644 src/content/docs/workers/vite-plugin/api.mdx create mode 100644 src/content/docs/workers/vite-plugin/cloudflare-environments.mdx create mode 100644 src/content/docs/workers/vite-plugin/get-started.mdx create mode 100644 src/content/docs/workers/vite-plugin/index.mdx create mode 100644 src/content/docs/workers/vite-plugin/migrating-from-wrangler-dev.mdx create mode 100644 src/content/docs/workers/vite-plugin/secrets.mdx create mode 100644 src/content/docs/workers/vite-plugin/tutorial.mdx diff --git a/src/content/docs/workers/vite-plugin/api.mdx b/src/content/docs/workers/vite-plugin/api.mdx new file mode 100644 index 000000000000000..f02c4c0661c7ed5 --- /dev/null +++ b/src/content/docs/workers/vite-plugin/api.mdx @@ -0,0 +1,69 @@ +--- +pcx_content_type: reference +title: API +head: [] +sidebar: + order: 3 +description: Vite plugin API +--- + +### `cloudflare` + +The `cloudflare` plugin should be included in the Vite `plugins` array: + +```ts {4, 7} +// vite.config.ts + +import { defineConfig } from "vite"; +import { cloudflare } from "@cloudflare/vite-plugin"; + +export default defineConfig({ + plugins: [cloudflare()], +}); +``` + +It accepts an optional `PluginConfig` parameter. + +### `interface PluginConfig` + +- `configPath?: string` + + An optional path to your Worker config file. + By default, a `wrangler.toml`, `wrangler.json`, or `wrangler.jsonc` file in the root of your application will be used as the Worker config. + +- `viteEnvironment?: { name?: string }` + + Optional Vite environment options. + By default, the environment name is the Worker name with `-` characters replaced with `_`. + Setting the name here will override this. + +- `persistState?: boolean | { path: string }` + + An optional override for state persistence. + By default, state is persisted to `.wrangler/state` in a `v3` subdirectory. + A custom `path` can be provided or, alternatively, persistence can be disabled by setting the value to `false`. + +- `auxiliaryWorkers?: Array` + + An optional array of auxiliary workers. + You can use [service bindings](/workers/runtime-apis/bindings/service-bindings/) to call auxiliary workers from your main (entry) Worker. + All requests are routed through your entry Worker. + During the build, each Worker is output to a separate subdirectory of `dist`. + +:::note +When running `wrangler deploy`, only your main (entry) Worker will be deployed. +If using multiple Workers, each must be deployed individually. +You can inspect the `dist` directory and then run `wrangler deploy -c path-to-worker-output-config` for each. +::: + +### `interface AuxiliaryWorkerConfig` + +- `configPath: string` + + A required path to your Worker config file. + +- `viteEnvironment?: { name?: string }` + + Optional Vite environment options. + By default, the environment name is the Worker name with `-` characters replaced with `_`. + Setting the name here will override this. diff --git a/src/content/docs/workers/vite-plugin/cloudflare-environments.mdx b/src/content/docs/workers/vite-plugin/cloudflare-environments.mdx new file mode 100644 index 000000000000000..50ada712a0c62e2 --- /dev/null +++ b/src/content/docs/workers/vite-plugin/cloudflare-environments.mdx @@ -0,0 +1,100 @@ +--- +pcx_content_type: concept +title: Cloudflare Environments +head: [] +sidebar: + order: 4 +description: Using Cloudflare environments with the Vite plugin +--- + +import { PackageManagers, WranglerConfig } from "~/components"; + +A Worker config file may contain configuration for multiple [Cloudflare environments](/workers/wrangler/environments/). +With the Cloudflare Vite plugin, you select a Cloudflare environment at dev or build time by providing the `CLOUDFLARE_ENV` environment variable. +Consider the following example Worker config file: + + + +```toml +name = "my-worker" +compatibility_date = "2024-12-30" +main = "./src/index.ts" + +vars = { MY_VAR = "Top-level var" } + +[env.staging] +vars = { MY_VAR = "Staging var" } + +[env.production] +vars = { MY_VAR = "Production var" } +``` + + + +If you run `CLOUDFLARE_ENV=production vite build` then the output `wrangler.json` file generated by the build will be a flattened configuration for the 'production' Cloudflare environment. +This combines [top-level only](/workers/wrangler/configuration/#top-level-only-keys), [inheritable](/workers/wrangler/configuration/#inheritable-keys), and [non-inheritable](/workers/wrangler/configuration/#non-inheritable-keys) keys. +The value of `MY_VAR` will therefore be `'Production var'`. +The name of the Worker will be `'my-worker-production'`. +This is because the environment name is automatically appended to the top-level Worker name. + +:::note +The default Vite environment name for a Worker is always the top-level Worker name. +This enables you to reference the Worker consistently in your Vite config when using multiple Cloudflare environments. +::: + +Cloudflare environments can also be used in development. +For example, you could run `CLOUDFLARE_ENV=development vite dev`. +It is common to use the default top-level environment as the development environment and then add additional environments as necessary. + +:::note +Running `vite dev` or `vite build` without providing `CLOUDFLARE_ENV` will use the default top-level Cloudflare environment. +The value of `MY_VAR` in the example above would therefore be `'Top-level var'`. +As Cloudflare environments are applied at dev and build time, specifying `CLOUDFLARE_ENV` when running `vite preview` or `wrangler deploy` will have no effect. +::: + +### Combining Cloudflare environments and Vite modes + +You may wish to combine the concepts of [Cloudflare environments](/workers/wrangler/environments/) and [Vite modes](https://vite.dev/guide/env-and-mode.html#modes). +With this approach, the Vite mode can be used to select the Cloudflare environment and a single method can be used to determine environment specific configuration and code. +Consider again the previous example: + + + +```toml +# wrangler.toml + +name = "my-worker" +compatibility_date = "2024-12-30" +main = "./src/index.ts" + +vars = { MY_VAR = "Top-level var" } + +[env.staging] +vars = { MY_VAR = "Staging var" } + +[env.production] +vars = { MY_VAR = "Production var" } +``` + + + +Next, provide `.env.staging` and `.env.production` files: + +```sh +# .env.staging + +CLOUDFLARE_ENV=staging +``` + +```sh +# .env.production + +CLOUDFLARE_ENV=production +``` + +By default, `vite build` uses the 'production' Vite mode. +Vite will therefore load the `.env.production` file to get the environment variables that are used in the build. +Since the `.env.production` file contains `CLOUDFLARE_ENV=production`, the Cloudflare Vite plugin will select the 'production' Cloudflare environment. +The value of `MY_VAR` will therefore be `'Production var'`. +If you run `vite build --mode staging` then the 'staging' Vite mode will be used and the 'staging' Cloudflare environment will be selected. +The value of `MY_VAR` will therefore be `'Staging var'`. diff --git a/src/content/docs/workers/vite-plugin/get-started.mdx b/src/content/docs/workers/vite-plugin/get-started.mdx new file mode 100644 index 000000000000000..51d17209f49a94e --- /dev/null +++ b/src/content/docs/workers/vite-plugin/get-started.mdx @@ -0,0 +1,73 @@ +--- +pcx_content_type: get-started +title: Get started +head: [] +sidebar: + order: 1 +description: Get started with the Vite plugin +--- + +import { PackageManagers, WranglerConfig } from "~/components"; + +### Start with a basic `package.json` + +```json +{ + "name": "cloudflare-vite-quick-start", + "private": true, + "version": "0.0.0", + "type": "module", + "scripts": { + "dev": "vite", + "build": "vite build", + "preview": "vite preview" + } +} +``` + +:::note +Ensure that you include `"type": "module"` in order to use ES modules by default. +::: + +### Install the dependencies + + + +### Create your Vite config file and include the Cloudflare plugin + +```ts +// vite.config.ts + +import { defineConfig } from "vite"; +import { cloudflare } from "@cloudflare/vite-plugin"; + +export default defineConfig({ + plugins: [cloudflare()], +}); +``` + +### Create your Worker config file + + + +```toml +name = "cloudflare-vite-quick-start" +compatibility_date = "2024-12-30" +main = "./src/index.ts" +``` + + + +### Create your Worker entry file + +```ts +// src/index.ts + +export default { + fetch() { + return new Response(`Running in ${navigator.userAgent}!`); + }, +}; +``` + +You can now develop (`npm run dev`), build (`npm run build`), preview (`npm run preview`), and deploy (`npm exec wrangler deploy`) your application. diff --git a/src/content/docs/workers/vite-plugin/index.mdx b/src/content/docs/workers/vite-plugin/index.mdx new file mode 100644 index 000000000000000..86f848391a560f8 --- /dev/null +++ b/src/content/docs/workers/vite-plugin/index.mdx @@ -0,0 +1,20 @@ +--- +pcx_content_type: overview +title: Vite plugin +sidebar: + # order: + group: + badge: Beta +head: [] +description: A full-featured integration between Vite and the Workers runtime +--- + +The Cloudflare Vite plugin enables a full-featured integration between Vite and the Workers runtime. +Your Worker code runs inside [workerd](https://github.com/cloudflare/workerd), matching the production behavior as closely as possible and providing confidence as you develop and deploy your applications. + +### Features + +- Provides direct access to Workers runtime APIs and bindings +- Supports Workers Assets, enabling you to build static sites, SPAs, and full-stack applications +- Leverages Vite's hot module replacement for consistently fast updates +- Supports `vite preview` for previewing your build output in the Workers runtime prior to deployment diff --git a/src/content/docs/workers/vite-plugin/migrating-from-wrangler-dev.mdx b/src/content/docs/workers/vite-plugin/migrating-from-wrangler-dev.mdx new file mode 100644 index 000000000000000..57900b13f6d8e5f --- /dev/null +++ b/src/content/docs/workers/vite-plugin/migrating-from-wrangler-dev.mdx @@ -0,0 +1,23 @@ +--- +pcx_content_type: concept +title: Migrating from wrangler dev +head: [] +sidebar: + order: 6 +description: Migrating from wrangler dev to the Vite plugin +--- + +Migrating from `wrangler dev` is a simple process and you can follow the instructions in [Get started](../get-started/). +There are a few key differences to highlight: + +### Input and output Worker config files + +In the Vite integration, your Worker config file (for example, `wrangler.toml`) is the input configuration and a separate output configuration is created as part of the build. +This output file is a snapshot of your configuration at the time of the build and is modified to reference your build artifacts. +It is the configuration that is used for preview and deployment. + +### Redundant fields in the Wrangler config file + +There are various options in the Worker config file that are ignored when using Vite, as they are either no longer applicable or are replaced by Vite equivalents. +If these options are provided, then warnings will be printed to the console with suggestions for how to proceed. +Examples where the Vite configuration should be used instead include `alias` and `define`. diff --git a/src/content/docs/workers/vite-plugin/secrets.mdx b/src/content/docs/workers/vite-plugin/secrets.mdx new file mode 100644 index 000000000000000..cfc25611d227755 --- /dev/null +++ b/src/content/docs/workers/vite-plugin/secrets.mdx @@ -0,0 +1,16 @@ +--- +pcx_content_type: concept +title: Secrets +head: [] +sidebar: + order: 5 +description: Using secrets with the Vite plugin +--- + +import { PackageManagers, WranglerConfig } from "~/components"; + +Secrets can be provided to your Worker in local development using a [`.dev.vars`](/workers/configuration/secrets/#local-development-with-secrets) file. If you are using [Cloudflare Environments](../cloudflare-environments) then the relevant `.dev.vars` file will be selected. For example, `CLOUDFLARE_ENV=staging vite dev` will load `.dev.vars.staging` if it exists and fall back to `.dev.vars`. + +:::note +The `vite build` command copies the relevant `.dev.vars[.env-name]` file to the output directory. This is only used when running `vite preview` and is not deployed with your Worker. +::: diff --git a/src/content/docs/workers/vite-plugin/tutorial.mdx b/src/content/docs/workers/vite-plugin/tutorial.mdx new file mode 100644 index 000000000000000..20c202bd753caa3 --- /dev/null +++ b/src/content/docs/workers/vite-plugin/tutorial.mdx @@ -0,0 +1,252 @@ +--- +pcx_content_type: tutorial +title: Tutorial +head: [] +sidebar: + order: 2 +description: Create a React SPA with an API Worker using the Vite plugin +--- + +import { PackageManagers, WranglerConfig } from "~/components"; + +In this tutorial, you will create a React SPA that can be deployed as a Worker with Workers Assets. +You will then add an API Worker that can be accessed from the front-end code. +You will develop, build, and preview the application using Vite before finally deploying to Cloudflare. + +### Set up and configure the React SPA + +#### Scaffold a Vite project + +Start by creating a React TypeScript project with Vite. + + + +Open the `cloudflare-vite-tutorial` directory in your editor of choice. + +#### Add the Cloudflare dependencies + + + +#### Add the plugin to your Vite config + +```ts {5, 8} +// vite.config.ts + +import { defineConfig } from "vite"; +import react from "@vitejs/plugin-react"; +import { cloudflare } from "@cloudflare/vite-plugin"; + +export default defineConfig({ + plugins: [react(), cloudflare()], +}); +``` + +#### Create your Worker config file + + + +```toml +name = "cloudflare-vite-tutorial" +compatibility_date = "2024-12-30" +assets = { not_found_handling = "single-page-application" } +``` + + + +The [`not_found_handling`](/workers/static-assets/routing/#not_found_handling--404-page--single-page-application--none) value has been set to `single-page-application`. +This means that all not found requests will serve the `index.html` file. +With the Cloudflare plugin, the `assets` routing configuration is used in place of Vite's default behavior. +This ensures that your application's routing works the same way while developing as it does when deployed to production. + +Note that the [`directory`](/workers/static-assets/binding/#directory) field is not used when configuring assets with Vite. +The `directory` in the output configuration will automatically point to the client build output. + +:::note +When using the Cloudflare Vite plugin, the Worker config (for example, `wrangler.toml`) that you provide is the input configuration file. +A separate output `wrangler.json` file is created when you run `vite build`. +This output file is a snapshot of your configuration at the time of the build and is modified to reference your build artifacts. +It is the configuration that is used for preview and deployment. +::: + +#### Run the development server + +Run `npm run dev` to verify that your application is working as expected. + +For a purely front-end application, you could now build (`npm run build`), preview (`npm run preview`), and deploy (`npm exec wrangler deploy`) your application. +However, this tutorial will show you how to go a step further and add an API Worker. + +### Add an API Worker + +#### Configure TypeScript for your Worker code + + + +```jsonc +// tsconfig.worker.json + +{ + "extends": "./tsconfig.node.json", + "compilerOptions": { + "tsBuildInfoFile": "./node_modules/.tmp/tsconfig.worker.tsbuildinfo", + "types": ["@cloudflare/workers-types/2023-07-01", "vite/client"], + }, + "include": ["api"], +} +``` + +```jsonc {8} +// tsconfig.json + +{ + "files": [], + "references": [ + { "path": "./tsconfig.app.json" }, + { "path": "./tsconfig.node.json" }, + { "path": "./tsconfig.worker.json" }, + ], +} +``` + +#### Add to your Worker configuration + + + +```toml +name = "cloudflare-vite-tutorial" +compatibility_date = "2024-12-30" +assets = { not_found_handling = "single-page-application", binding = "ASSETS" } +main = "./api/index.ts" +``` + + + +The assets `binding` defined here will allow you to access the assets functionality from your Worker. + +#### Add your API Worker + +```ts +// api/index.ts + +interface Env { + ASSETS: Fetcher; +} + +export default { + fetch(request, env) { + const url = new URL(request.url); + + if (url.pathname.startsWith("/api/")) { + return Response.json({ + name: "Cloudflare", + }); + } + + return env.ASSETS.fetch(request); + }, +} satisfies ExportedHandler; +``` + +The Worker above will be invoked for any request not matching a static asset. +It returns a JSON response if the `pathname` starts with `/api/` and otherwise passes the incoming request through to the assets binding. +This means that for paths that do not start with `/api/`, the `not_found_handling` behavior defined in the Worker config will be evaluated and the `index.html` file will be returned, enabling SPA navigations. + +#### Call the API from the client + +Edit `src/App.tsx` so that it includes an additional button that calls the API and sets some state: + +```tsx {10, 34-48} collapse={14-29} +// src/App.tsx + +import { useState } from "react"; +import reactLogo from "./assets/react.svg"; +import viteLogo from "/vite.svg"; +import "./App.css"; + +function App() { + const [count, setCount] = useState(0); + const [name, setName] = useState("unknown"); + + return ( + <> + +

Vite + React

+
+ +

+ Edit src/App.tsx and save to test HMR +

+
+
+ +

+ Edit api/index.ts to change the name +

+
+

+ Click on the Vite and React logos to learn more +

+ + ); +} + +export default App; +``` + +Now, if you click the button, it will display 'Name from API is: Cloudflare'. + +Increment the counter to update the application state in the browser. +Next, edit `api/index.ts` by changing the `name` it returns to `'Cloudflare Workers'`. +If you click the button again, it will display the new `name` while preserving the previously set counter value. +With Vite and the Cloudflare plugin, you can iterate on the client and server parts of your app quickly without losing UI state between edits. + +#### Build your application + +Run `npm run build` to build your application. + +If you inspect the `dist` directory, you will see that it contains two subdirectories: `client` and `cloudflare-vite-tutorial`. +The `cloudflare-vite-tutorial` directory contains your Worker code and the output `wrangler.json` configuration. + +#### Preview your application + +Run `npm run preview` to validate that your application runs as expected. +This command will run your build output locally in the Workers runtime, closely matching its behaviour in production. + +#### Deploy to Cloudflare + +Run `npm exec wrangler deploy` to deploy your application to Cloudflare. +This command will automatically use the output `wrangler.json` that was included in the build output. + +### Next steps + +In this tutorial, we created an SPA that could be deployed as a Worker with Workers Assets. +We then added an API Worker that could be accessed from the front-end code and deployed to Cloudflare. +Possible next steps include: + +- Adding a binding to another Cloudflare service such as a [KV namespace](/kv/) or [D1 database](/d1/) +- Expanding the API to include additional routes +- Using a library, such as [tRPC](https://trpc.io/) or [Hono](https://hono.dev/), in your API Worker From 3d72d855b3afe78da6be006f3052a5f2da34a672 Mon Sep 17 00:00:00 2001 From: James Opstad <13586373+jamesopstad@users.noreply.github.com> Date: Mon, 3 Mar 2025 15:53:29 +0000 Subject: [PATCH 02/34] Update src/content/docs/workers/vite-plugin/api.mdx Co-authored-by: hyperlint-ai[bot] <154288675+hyperlint-ai[bot]@users.noreply.github.com> --- src/content/docs/workers/vite-plugin/api.mdx | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/content/docs/workers/vite-plugin/api.mdx b/src/content/docs/workers/vite-plugin/api.mdx index f02c4c0661c7ed5..16e12cf0d9ee80a 100644 --- a/src/content/docs/workers/vite-plugin/api.mdx +++ b/src/content/docs/workers/vite-plugin/api.mdx @@ -45,7 +45,7 @@ It accepts an optional `PluginConfig` parameter. - `auxiliaryWorkers?: Array` - An optional array of auxiliary workers. + An optional array of auxiliary Workers. You can use [service bindings](/workers/runtime-apis/bindings/service-bindings/) to call auxiliary workers from your main (entry) Worker. All requests are routed through your entry Worker. During the build, each Worker is output to a separate subdirectory of `dist`. From faa371a402283fb28623b342b715ff028c4be2f4 Mon Sep 17 00:00:00 2001 From: James Opstad <13586373+jamesopstad@users.noreply.github.com> Date: Mon, 3 Mar 2025 15:53:43 +0000 Subject: [PATCH 03/34] Update src/content/docs/workers/vite-plugin/api.mdx Co-authored-by: hyperlint-ai[bot] <154288675+hyperlint-ai[bot]@users.noreply.github.com> --- src/content/docs/workers/vite-plugin/api.mdx | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/content/docs/workers/vite-plugin/api.mdx b/src/content/docs/workers/vite-plugin/api.mdx index 16e12cf0d9ee80a..0812dd7f4e35e7d 100644 --- a/src/content/docs/workers/vite-plugin/api.mdx +++ b/src/content/docs/workers/vite-plugin/api.mdx @@ -46,7 +46,7 @@ It accepts an optional `PluginConfig` parameter. - `auxiliaryWorkers?: Array` An optional array of auxiliary Workers. - You can use [service bindings](/workers/runtime-apis/bindings/service-bindings/) to call auxiliary workers from your main (entry) Worker. + You can use [service bindings](/workers/runtime-apis/bindings/service-bindings/) to call auxiliary Workers from your main (entry) Worker. All requests are routed through your entry Worker. During the build, each Worker is output to a separate subdirectory of `dist`. From 73499b9e97745cdcc628084c912d65fd4eb98890 Mon Sep 17 00:00:00 2001 From: korinne Date: Thu, 6 Mar 2025 07:21:39 -0800 Subject: [PATCH 04/34] adds a directory structure for local development docs, and adds a Vite plugin section --- .../docs/workers/local-development/index.mdx | 18 + .../docs/workers/local-development/vite.mdx | 308 ++++++++++++++++++ .../workers/local-development/wrangler.mdx | 137 ++++++++ src/content/docs/workers/vite-plugin/api.mdx | 69 ---- .../vite-plugin/cloudflare-environments.mdx | 100 ------ .../docs/workers/vite-plugin/get-started.mdx | 73 ----- .../docs/workers/vite-plugin/index.mdx | 20 -- .../migrating-from-wrangler-dev.mdx | 23 -- .../docs/workers/vite-plugin/secrets.mdx | 16 - .../docs/workers/vite-plugin/tutorial.mdx | 252 -------------- 10 files changed, 463 insertions(+), 553 deletions(-) create mode 100644 src/content/docs/workers/local-development/index.mdx create mode 100644 src/content/docs/workers/local-development/vite.mdx create mode 100644 src/content/docs/workers/local-development/wrangler.mdx delete mode 100644 src/content/docs/workers/vite-plugin/api.mdx delete mode 100644 src/content/docs/workers/vite-plugin/cloudflare-environments.mdx delete mode 100644 src/content/docs/workers/vite-plugin/get-started.mdx delete mode 100644 src/content/docs/workers/vite-plugin/index.mdx delete mode 100644 src/content/docs/workers/vite-plugin/migrating-from-wrangler-dev.mdx delete mode 100644 src/content/docs/workers/vite-plugin/secrets.mdx delete mode 100644 src/content/docs/workers/vite-plugin/tutorial.mdx diff --git a/src/content/docs/workers/local-development/index.mdx b/src/content/docs/workers/local-development/index.mdx new file mode 100644 index 000000000000000..1e5d49ae1314deb --- /dev/null +++ b/src/content/docs/workers/local-development/index.mdx @@ -0,0 +1,18 @@ +--- +pcx_content_type: navigation +title: Local development +sidebar: + order: 5 +head: [] +description: Develop your Workers locally. +--- + +Cloudflare Workers provides two primary ways to develop and test your code locally. Local development ensures a fast feedback loop, keeps iteration times low, and lets you experiment before deploying to production. + +Developers can locally test their changes to a Workers project using the following: + +- **Wrangler’s built-in dev command** [`wrangler dev`](/workers/wrangler/commands/#dev), which uses [`workerd`](https://github.com/cloudflare/workerd) and Miniflare to simulate production behavior and resource bindings locally. + +- The **Cloudflare Vite plugin** (`@cloudflare/vite-plugin`), which integrates directly with Vite and runs your code in the same `workerd` runtime, while also offering features like [hot module replacement (HMR)](https://vite.dev/guide/features.html#hot-module-replacement). The Vite plugin is currently considered in **beta**. + +Both approaches aim to provide confidence that your local environment will closely match the production runtime, removing the need to [test against remote resources](#develop-using-remote-resources-and-bindings). diff --git a/src/content/docs/workers/local-development/vite.mdx b/src/content/docs/workers/local-development/vite.mdx new file mode 100644 index 000000000000000..e987272d829cd68 --- /dev/null +++ b/src/content/docs/workers/local-development/vite.mdx @@ -0,0 +1,308 @@ +--- +title: Vite +pcx_content_type: concept +sidebar: + order: 7 + group: + badge: Beta +head: [] +description: Locally develop and test changes with the Cloudflare Vite plugin +--- + +import { + Badge, + InlineBadge, + PackageManagers, + WranglerConfig, +} from "~/components"; + +The Cloudflare Vite plugin (`@cloudflare/vite-plugin`) integrates your Worker code directly with [Vite](https://vite.dev/). Like `wrangler dev`, this approach uses `workerd` under the hood as well, and provides: + +- Direct access to Workers [runtime APIs](/workers/runtime-apis/) and [bindings](/runtime-apis/bindings/) +- [Hot module replacement (HMR)](https://vite.dev/guide/features.html#hot-module-replacement) for near-instant feedback on code changes. +- A single workflow (`vite dev`, `vite build`, `vite preview`) that handles both your client-side assets and Worker code. +- An “input” Wrangler config file and an automatically generated “output” config file (used for preview and deployment). + +If you are building anything that involves a front-end using [Workers static assets](/workers/static-assets/), the Vite approach can be particularly powerful. + +## Get started + +#### 1. Create your project directory and add a minimal package.json: + +```json +{ + "name": "cloudflare-vite-quick-start", + "private": true, + "version": "0.0.0", + "type": "module", + "scripts": { + "dev": "vite", + "build": "vite build", + "preview": "vite preview" + } +} +``` + +:::note +Ensure that you include `"type": "module"` in order to use ES modules by default. +::: + +#### 2. Install dependencies + + + +#### 3. Create a Vite config file (`vite.config.ts`) and include the Cloudflare plugin: + +```ts +// vite.config.ts + +import { defineConfig } from "vite"; +import { cloudflare } from "@cloudflare/vite-plugin"; + +export default defineConfig({ + plugins: [cloudflare()], +}); +``` + +#### 4. Create a Worker configuration file (`wrangler.toml` or `wrangler.jsonc`): + + + +```toml +name = "cloudflare-vite-quick-start" +compatibility_date = "2024-12-30" +main = "./src/index.ts" +``` + + + +#### 5. Create a Worker entry file (`src/index.ts`): + +```ts +// src/index.ts + +export default { + fetch() { + return new Response(`Running in ${navigator.userAgent}!`); + }, +}; +``` + +#### 6. Run local development + +```sh +npm run dev +``` + +This starts a local development server, using the Workers runtime behind the scenes. You can build (`npm run build)`, preview (`npm run preview`), or deploy (`npm exec wrangler deploy`) at any time. + +## Cloudflare environments + +You can specify multiple [Cloudflare environments](/workers/wrangler/environments/) in your Worker confiuration (for example, `[env.staging]` or `[env.production]`). With the Cloudflare Vite plugin, you can select an environment at `dev` or `build` time by providing the `CLOUDFLARE_ENV` environment variable. + +For example, let's say you have the following Wrangler configuration file: + + + +```toml +name = "my-worker" +compatibility_date = "2024-12-30" +main = "./src/index.ts" + +vars = { MY_VAR = "Top-level var" } + +[env.staging] +vars = { MY_VAR = "Staging var" } + +[env.production] +vars = { MY_VAR = "Production var" } +``` + + + +With the Vite plugin, you can run: + +```sh +CLOUDFLARE_ENV=production vite build +``` + +The output `wrangler.json` file generated by the build will be a flattened configuration for the `'production'` Cloudflare environment. This combines [top-level only](/workers/wrangler/configuration/#top-level-only-keys), [inheritable](/workers/wrangler/configuration/#inheritable-keys), and [non-inheritable](/workers/wrangler/configuration/#non-inheritable-keys) keys. + +In this case, + +- The value of `MY_VAR` will be `'Production var'`. +- The name of the Worker will be `'my-worker-production'`. + +This is because the environment name is automatically appended to the top-level Worker name. + +:::note +The default Vite environment name for a Worker is always the top-level Worker name. +This enables you to reference the Worker consistently in your Vite config when using multiple Cloudflare environments. +::: + +### Cloudflare Environments during development + +You can also specify Cloudflare environments in development. For example, you could run: + +```sh +CLOUDFLARE_ENV=development vite dev +``` + +It is common to use the default top-level environment as the development environment and then add additional environments as necessary. + +:::note +Running `vite dev` or `vite build` without providing `CLOUDFLARE_ENV` will use the default top-level Cloudflare environment. +In the above example, the value of `MY_VAR` would be `'Top-level var'`. +Since Cloudflare environments are applied at `dev` and `build` time, specifying `CLOUDFLARE_ENV` when running `vite preview` or `wrangler deploy` will have no effect. +::: + +### Combining Cloudflare Environments and Vite Modes + +You may want to combine the concepts of [Cloudflare environments](/workers/wrangler/environments/) and [Vite modes](https://vite.dev/guide/env-and-mode.html#modes). + +With this approach, the Vite mode can be used to select the Cloudflare environment and a single method can be used to determine environment specific configuration and code. + +Let's use the previous example: + + + +```toml +# wrangler.toml + +name = "my-worker" +compatibility_date = "2024-12-30" +main = "./src/index.ts" + +vars = { MY_VAR = "Top-level var" } + +[env.staging] +vars = { MY_VAR = "Staging var" } + +[env.production] +vars = { MY_VAR = "Production var" } +``` + + + +Next, provide `.env.staging` and `.env.production` files: + +```sh +# .env.staging + +CLOUDFLARE_ENV=staging +``` + +```sh +# .env.production + +CLOUDFLARE_ENV=production +``` + +By default, `vite build` uses the **'production'** Vite mode, which loads `.env.production` to get the environment variables that are used in the build. + +- This sets `CLOUDFLARE_ENV=production`, selecting the production Cloudflare environment. +- `MY_VAR` becomes `'Production var'`. + +To build with the **staging mode**, run: + +```sh +vite build --mode staging +``` + +- This loads `.env.staging`. +- The value of `MY_VAR` will be `'Staging var'`. + +## Secrets in local development + +Secrets can be provided to your Worker in local development using a [`.dev.vars`](/workers/configuration/secrets/#local-development-with-secrets) file. If you are using [Cloudflare Environments](../cloudflare-environments) then the relevant `.dev.vars` file will be selected. + +For example, + +```sh +CLOUDFLARE_ENV=staging vite dev +``` + +Will load `.dev.vars.staging` if it exists (falling back to `.dev.vars` if otherwise). + +:::note +When you run `vite build`, the relevant `.dev.vars[.env-name]` file is copied to the output directory for use during `vite preview`. It is **not** deployed with your Worker. +::: + +## Migrating from `wrangler dev` + +Migrating from `wrangler dev` is a simple process and you can follow the instructions in [Get started](../get-started/). + +There are a few key differences to highlight: + +#### 1. Input and output Worker configuration files + +- Your existing Wrangler configuration file is treated as an **input** configuration. +- A separate output configuration is generated at build time, capturing a snapshot of your config and referencing your build artifacts. This is the configuration that is used for **preview** and **deployment**. + +#### 2. Redundant fields in the Wrangler configuration file + +- Some fields are either ignored or replaced by Vite options, as they are either no longer applicable or are replaced by Vite equivalents. +- If these options are provided, then warnings will be printed to the console with suggestions for how to proceed. For example, you will see console warnings if you use fields like `alias` or `define` that have direct Vite equivalents. + +## API + +### `cloudflare` + +The `cloudflare` plugin should be included in the Vite `plugins` array: + +```ts {4, 7} +// vite.config.ts + +import { defineConfig } from "vite"; +import { cloudflare } from "@cloudflare/vite-plugin"; + +export default defineConfig({ + plugins: [cloudflare()], +}); +``` + +It accepts an optional `PluginConfig` parameter. + +### `interface PluginConfig` + +- `configPath?: string` + + An optional path to your Worker config file. + By default, a `wrangler.toml`, `wrangler.json`, or `wrangler.jsonc` file in the root of your application will be used as the Worker config. + +- `viteEnvironment?: { name?: string }` + + Optional Vite environment options. + By default, the environment name is the Worker name with `-` characters replaced with `_`. + Setting the name here will override this. + +- `persistState?: boolean | { path: string }` + + An optional override for state persistence. + By default, state is persisted to `.wrangler/state` in a `v3` subdirectory. + A custom `path` can be provided or, alternatively, persistence can be disabled by setting the value to `false`. + +- `auxiliaryWorkers?: Array` + + An optional array of auxiliary Workers. + You can use [service bindings](/workers/runtime-apis/bindings/service-bindings/) to call auxiliary Workers from your main (entry) Worker. + All requests are routed through your entry Worker. + During the build, each Worker is output to a separate subdirectory of `dist`. + +:::note +When running `wrangler deploy`, only your main (entry) Worker will be deployed. +If using multiple Workers, each must be deployed individually. +You can inspect the `dist` directory and then run `wrangler deploy -c path-to-worker-output-config` for each. +::: + +### `interface AuxiliaryWorkerConfig` + +- `configPath: string` + + A required path to your Worker config file. + +- `viteEnvironment?: { name?: string }` + + Optional Vite environment options. + By default, the environment name is the Worker name with `-` characters replaced with `_`. + Setting the name here will override this. diff --git a/src/content/docs/workers/local-development/wrangler.mdx b/src/content/docs/workers/local-development/wrangler.mdx new file mode 100644 index 000000000000000..0a8b0c13dcc0549 --- /dev/null +++ b/src/content/docs/workers/local-development/wrangler.mdx @@ -0,0 +1,137 @@ +--- +title: Wrangler +pcx_content_type: concept +sidebar: + order: 6 +head: [] +description: Locally develop and test changes with `wrangler dev` +--- + +## Start a local development server + +:::note + +This guide assumes you are using [Wrangler v3.0](https://blog.cloudflare.com/wrangler3/) or later. + +Users new to Wrangler CLI and Cloudflare Workers should visit the [Wrangler Install/Update guide](/workers/wrangler/install-and-update) to install `wrangler`. + +::: + +Wrangler provides a [`dev`](/workers/wrangler/commands/#dev) command that starts a local server for developing your Worker. Make sure you have `npm` installed and run the following in the folder containing your Worker application: + +```sh +npx wrangler dev +``` + +`wrangler dev` will run the Worker directly on your local machine. `wrangler dev` uses a combination of `workerd` and [Miniflare](https://github.com/cloudflare/workers-sdk/tree/main/packages/miniflare), a simulator that allows you to test your Worker against additional resources like KV, Durable Objects, WebSockets, and more. + +### Supported resource bindings in different environments + +| Product | Local Dev Supported | Remote Dev Supported | +| ----------------------------------- | ------------------- | -------------------- | +| AI | ✅[^1] | ✅ | +| Assets | ✅ | ✅ | +| Analytics Engine | ✅ | ✅ | +| Browser Rendering | ❌ | ✅ | +| D1 | ✅ | ✅ | +| Durable Objects | ✅ | ✅ | +| Email Bindings | ❌ | ✅ | +| Hyperdrive | ✅ | ✅ | +| Images | ✅ | ✅ | +| KV | ✅ | ✅ | +| mTLS | ❌ | ✅ | +| Queues | ✅ | ❌ | +| R2 | ✅ | ✅ | +| Rate Limiting | ✅ | ✅ | +| Service Bindings (multiple workers) | ✅ | ✅ | +| Vectorize | ✅[^2] | ✅ | +| Workflows | ✅ | ❌ | + +With any bindings that are not supported locally, you will need to use the [`--remote` command](#develop-using-remote-resources-and-bindings) in wrangler, such as `wrangler dev --remote`. + +[^1]: Using Workers AI always accesses your Cloudflare account in order to run AI models and will incur usage charges even in local development. + +[^2]: Using Vectorize always accesses your Cloudflare account to run queries, and will incur usage charges even in local development. + +## Work with local data + +When running `wrangler dev`, resources such as KV, Durable Objects, D1, and R2 will be stored and persisted locally and not affect the production resources. + +### Use bindings in Wrangler configuration files + +[Wrangler](/workers/wrangler/) will automatically create local versions of bindings found in the [Wrangler configuration file](/workers/wrangler/configuration/). These local resources will not have data in them initially, so you will need to add data manually via Wrangler commands and the [`--local` flag](#use---local-flag). + +When you run `wrangler dev` Wrangler stores local resources in a `.wrangler/state` folder, which is automatically created. + +If you prefer to specify a directory, you can use the [`--persist-to`](/workers/wrangler/commands/#dev) flag with `wrangler dev` like this: + +```sh +npx wrangler dev --persist-to +``` + +Using this will write all local storage and cache to the specified directory instead of `.wrangler`. + +:::note + +This local persistence folder should be added to your `.gitignore` file. + +::: + +### Use `--local` flag + +The following [Wrangler commands](/workers/wrangler/commands/) have a `--local` flag which allows you to create, update, and delete local data during development: + +| Command | +| ---------------------------------------------------- | +| [`d1 execute`](/workers/wrangler/commands/#execute) | +| [`kv key`](/workers/wrangler/commands/#kv-key) | +| [`kv bulk`](/workers/wrangler/commands/#kv-bulk) | +| [`r2 object`](/workers/wrangler/commands/#r2-object) | + +If using `--persist-to` to specify a custom folder with `wrangler dev` you should also add `--persist-to` with the same directory name along with the `--local` flag when running the commands above. For example, to put a custom KV key into a local namespace via the CLI you would run: + +```sh +npx wrangler kv key put test 12345 --binding MY_KV_NAMESPACE --local --persist-to worker-local +``` + +Running `wrangler kv key put` will create a new key `test` with a value of `12345` on the local namespace specified via the binding `MY_KV_NAMESPACE` in the [Wrangler configuration file](/workers/wrangler/configuration/). This example command sets the local persistence directory to `worker-local` using `--persist-to`, to ensure that the data is created in the correct location. If `--persist-to` was not set, it would create the data in the `.wrangler` folder. + +### Clear Wrangler's local storage + +If you need to clear local storage entirely, delete the `.wrangler/state` folder. You can also be more fine-grained and delete specific resource folders within `.wrangler/state`. + +Any deleted folders will be created automatically the next time you run `wrangler dev`. + +## Local-only environment variables + +When running `wrangler dev`, variables in the [Wrangler configuration file](/workers/wrangler/configuration/) are automatically overridden by values defined in a `.dev.vars` file located in the root directory of your worker. This is useful for providing values you do not want to check in to source control. + +```shell +API_HOST = "localhost:4000" +API_ACCOUNT_ID = "local_example_user" +``` + +## Develop using remote resources and bindings + +There may be times you want to develop against remote resources and bindings. To run `wrangler dev` in remote mode, add the `--remote` flag, which will run both your code and resources remotely: + +```sh +npx wrangler dev --remote +``` + +For some products like KV and R2, remote resources used for `wrangler dev --remote` must be specified with preview ID/names in the [Wrangler configuration file](/workers/wrangler/configuration/) such as `preview_id` for KV or `preview_bucket name` for R2. Resources used for remote mode (preview) can be different from resources used for production to prevent changing production data during development. To use production data in `wrangler dev --remote`, set the preview ID/name of the resource to the ID/name of your production resource. + +## Customize `wrangler dev` + +You can customize how `wrangler dev` works to fit your needs. Refer to [the `wrangler dev` documentation](/workers/wrangler/commands/#dev) for available configuration options. + +:::caution + +There is a bug associated with how outgoing requests are handled when using `wrangler dev --remote`. For more information, read the [Known issues section](/workers/platform/known-issues/#wrangler-dev). + +::: + +## Related resources + +- [D1 local development](/d1/best-practices/local-development/) - The official D1 guide to local development and testing. +- [DevTools](/workers/observability/dev-tools) - Guides to using DevTools to debug your Worker locally. diff --git a/src/content/docs/workers/vite-plugin/api.mdx b/src/content/docs/workers/vite-plugin/api.mdx deleted file mode 100644 index 0812dd7f4e35e7d..000000000000000 --- a/src/content/docs/workers/vite-plugin/api.mdx +++ /dev/null @@ -1,69 +0,0 @@ ---- -pcx_content_type: reference -title: API -head: [] -sidebar: - order: 3 -description: Vite plugin API ---- - -### `cloudflare` - -The `cloudflare` plugin should be included in the Vite `plugins` array: - -```ts {4, 7} -// vite.config.ts - -import { defineConfig } from "vite"; -import { cloudflare } from "@cloudflare/vite-plugin"; - -export default defineConfig({ - plugins: [cloudflare()], -}); -``` - -It accepts an optional `PluginConfig` parameter. - -### `interface PluginConfig` - -- `configPath?: string` - - An optional path to your Worker config file. - By default, a `wrangler.toml`, `wrangler.json`, or `wrangler.jsonc` file in the root of your application will be used as the Worker config. - -- `viteEnvironment?: { name?: string }` - - Optional Vite environment options. - By default, the environment name is the Worker name with `-` characters replaced with `_`. - Setting the name here will override this. - -- `persistState?: boolean | { path: string }` - - An optional override for state persistence. - By default, state is persisted to `.wrangler/state` in a `v3` subdirectory. - A custom `path` can be provided or, alternatively, persistence can be disabled by setting the value to `false`. - -- `auxiliaryWorkers?: Array` - - An optional array of auxiliary Workers. - You can use [service bindings](/workers/runtime-apis/bindings/service-bindings/) to call auxiliary Workers from your main (entry) Worker. - All requests are routed through your entry Worker. - During the build, each Worker is output to a separate subdirectory of `dist`. - -:::note -When running `wrangler deploy`, only your main (entry) Worker will be deployed. -If using multiple Workers, each must be deployed individually. -You can inspect the `dist` directory and then run `wrangler deploy -c path-to-worker-output-config` for each. -::: - -### `interface AuxiliaryWorkerConfig` - -- `configPath: string` - - A required path to your Worker config file. - -- `viteEnvironment?: { name?: string }` - - Optional Vite environment options. - By default, the environment name is the Worker name with `-` characters replaced with `_`. - Setting the name here will override this. diff --git a/src/content/docs/workers/vite-plugin/cloudflare-environments.mdx b/src/content/docs/workers/vite-plugin/cloudflare-environments.mdx deleted file mode 100644 index 50ada712a0c62e2..000000000000000 --- a/src/content/docs/workers/vite-plugin/cloudflare-environments.mdx +++ /dev/null @@ -1,100 +0,0 @@ ---- -pcx_content_type: concept -title: Cloudflare Environments -head: [] -sidebar: - order: 4 -description: Using Cloudflare environments with the Vite plugin ---- - -import { PackageManagers, WranglerConfig } from "~/components"; - -A Worker config file may contain configuration for multiple [Cloudflare environments](/workers/wrangler/environments/). -With the Cloudflare Vite plugin, you select a Cloudflare environment at dev or build time by providing the `CLOUDFLARE_ENV` environment variable. -Consider the following example Worker config file: - - - -```toml -name = "my-worker" -compatibility_date = "2024-12-30" -main = "./src/index.ts" - -vars = { MY_VAR = "Top-level var" } - -[env.staging] -vars = { MY_VAR = "Staging var" } - -[env.production] -vars = { MY_VAR = "Production var" } -``` - - - -If you run `CLOUDFLARE_ENV=production vite build` then the output `wrangler.json` file generated by the build will be a flattened configuration for the 'production' Cloudflare environment. -This combines [top-level only](/workers/wrangler/configuration/#top-level-only-keys), [inheritable](/workers/wrangler/configuration/#inheritable-keys), and [non-inheritable](/workers/wrangler/configuration/#non-inheritable-keys) keys. -The value of `MY_VAR` will therefore be `'Production var'`. -The name of the Worker will be `'my-worker-production'`. -This is because the environment name is automatically appended to the top-level Worker name. - -:::note -The default Vite environment name for a Worker is always the top-level Worker name. -This enables you to reference the Worker consistently in your Vite config when using multiple Cloudflare environments. -::: - -Cloudflare environments can also be used in development. -For example, you could run `CLOUDFLARE_ENV=development vite dev`. -It is common to use the default top-level environment as the development environment and then add additional environments as necessary. - -:::note -Running `vite dev` or `vite build` without providing `CLOUDFLARE_ENV` will use the default top-level Cloudflare environment. -The value of `MY_VAR` in the example above would therefore be `'Top-level var'`. -As Cloudflare environments are applied at dev and build time, specifying `CLOUDFLARE_ENV` when running `vite preview` or `wrangler deploy` will have no effect. -::: - -### Combining Cloudflare environments and Vite modes - -You may wish to combine the concepts of [Cloudflare environments](/workers/wrangler/environments/) and [Vite modes](https://vite.dev/guide/env-and-mode.html#modes). -With this approach, the Vite mode can be used to select the Cloudflare environment and a single method can be used to determine environment specific configuration and code. -Consider again the previous example: - - - -```toml -# wrangler.toml - -name = "my-worker" -compatibility_date = "2024-12-30" -main = "./src/index.ts" - -vars = { MY_VAR = "Top-level var" } - -[env.staging] -vars = { MY_VAR = "Staging var" } - -[env.production] -vars = { MY_VAR = "Production var" } -``` - - - -Next, provide `.env.staging` and `.env.production` files: - -```sh -# .env.staging - -CLOUDFLARE_ENV=staging -``` - -```sh -# .env.production - -CLOUDFLARE_ENV=production -``` - -By default, `vite build` uses the 'production' Vite mode. -Vite will therefore load the `.env.production` file to get the environment variables that are used in the build. -Since the `.env.production` file contains `CLOUDFLARE_ENV=production`, the Cloudflare Vite plugin will select the 'production' Cloudflare environment. -The value of `MY_VAR` will therefore be `'Production var'`. -If you run `vite build --mode staging` then the 'staging' Vite mode will be used and the 'staging' Cloudflare environment will be selected. -The value of `MY_VAR` will therefore be `'Staging var'`. diff --git a/src/content/docs/workers/vite-plugin/get-started.mdx b/src/content/docs/workers/vite-plugin/get-started.mdx deleted file mode 100644 index 51d17209f49a94e..000000000000000 --- a/src/content/docs/workers/vite-plugin/get-started.mdx +++ /dev/null @@ -1,73 +0,0 @@ ---- -pcx_content_type: get-started -title: Get started -head: [] -sidebar: - order: 1 -description: Get started with the Vite plugin ---- - -import { PackageManagers, WranglerConfig } from "~/components"; - -### Start with a basic `package.json` - -```json -{ - "name": "cloudflare-vite-quick-start", - "private": true, - "version": "0.0.0", - "type": "module", - "scripts": { - "dev": "vite", - "build": "vite build", - "preview": "vite preview" - } -} -``` - -:::note -Ensure that you include `"type": "module"` in order to use ES modules by default. -::: - -### Install the dependencies - - - -### Create your Vite config file and include the Cloudflare plugin - -```ts -// vite.config.ts - -import { defineConfig } from "vite"; -import { cloudflare } from "@cloudflare/vite-plugin"; - -export default defineConfig({ - plugins: [cloudflare()], -}); -``` - -### Create your Worker config file - - - -```toml -name = "cloudflare-vite-quick-start" -compatibility_date = "2024-12-30" -main = "./src/index.ts" -``` - - - -### Create your Worker entry file - -```ts -// src/index.ts - -export default { - fetch() { - return new Response(`Running in ${navigator.userAgent}!`); - }, -}; -``` - -You can now develop (`npm run dev`), build (`npm run build`), preview (`npm run preview`), and deploy (`npm exec wrangler deploy`) your application. diff --git a/src/content/docs/workers/vite-plugin/index.mdx b/src/content/docs/workers/vite-plugin/index.mdx deleted file mode 100644 index 86f848391a560f8..000000000000000 --- a/src/content/docs/workers/vite-plugin/index.mdx +++ /dev/null @@ -1,20 +0,0 @@ ---- -pcx_content_type: overview -title: Vite plugin -sidebar: - # order: - group: - badge: Beta -head: [] -description: A full-featured integration between Vite and the Workers runtime ---- - -The Cloudflare Vite plugin enables a full-featured integration between Vite and the Workers runtime. -Your Worker code runs inside [workerd](https://github.com/cloudflare/workerd), matching the production behavior as closely as possible and providing confidence as you develop and deploy your applications. - -### Features - -- Provides direct access to Workers runtime APIs and bindings -- Supports Workers Assets, enabling you to build static sites, SPAs, and full-stack applications -- Leverages Vite's hot module replacement for consistently fast updates -- Supports `vite preview` for previewing your build output in the Workers runtime prior to deployment diff --git a/src/content/docs/workers/vite-plugin/migrating-from-wrangler-dev.mdx b/src/content/docs/workers/vite-plugin/migrating-from-wrangler-dev.mdx deleted file mode 100644 index 57900b13f6d8e5f..000000000000000 --- a/src/content/docs/workers/vite-plugin/migrating-from-wrangler-dev.mdx +++ /dev/null @@ -1,23 +0,0 @@ ---- -pcx_content_type: concept -title: Migrating from wrangler dev -head: [] -sidebar: - order: 6 -description: Migrating from wrangler dev to the Vite plugin ---- - -Migrating from `wrangler dev` is a simple process and you can follow the instructions in [Get started](../get-started/). -There are a few key differences to highlight: - -### Input and output Worker config files - -In the Vite integration, your Worker config file (for example, `wrangler.toml`) is the input configuration and a separate output configuration is created as part of the build. -This output file is a snapshot of your configuration at the time of the build and is modified to reference your build artifacts. -It is the configuration that is used for preview and deployment. - -### Redundant fields in the Wrangler config file - -There are various options in the Worker config file that are ignored when using Vite, as they are either no longer applicable or are replaced by Vite equivalents. -If these options are provided, then warnings will be printed to the console with suggestions for how to proceed. -Examples where the Vite configuration should be used instead include `alias` and `define`. diff --git a/src/content/docs/workers/vite-plugin/secrets.mdx b/src/content/docs/workers/vite-plugin/secrets.mdx deleted file mode 100644 index cfc25611d227755..000000000000000 --- a/src/content/docs/workers/vite-plugin/secrets.mdx +++ /dev/null @@ -1,16 +0,0 @@ ---- -pcx_content_type: concept -title: Secrets -head: [] -sidebar: - order: 5 -description: Using secrets with the Vite plugin ---- - -import { PackageManagers, WranglerConfig } from "~/components"; - -Secrets can be provided to your Worker in local development using a [`.dev.vars`](/workers/configuration/secrets/#local-development-with-secrets) file. If you are using [Cloudflare Environments](../cloudflare-environments) then the relevant `.dev.vars` file will be selected. For example, `CLOUDFLARE_ENV=staging vite dev` will load `.dev.vars.staging` if it exists and fall back to `.dev.vars`. - -:::note -The `vite build` command copies the relevant `.dev.vars[.env-name]` file to the output directory. This is only used when running `vite preview` and is not deployed with your Worker. -::: diff --git a/src/content/docs/workers/vite-plugin/tutorial.mdx b/src/content/docs/workers/vite-plugin/tutorial.mdx deleted file mode 100644 index 20c202bd753caa3..000000000000000 --- a/src/content/docs/workers/vite-plugin/tutorial.mdx +++ /dev/null @@ -1,252 +0,0 @@ ---- -pcx_content_type: tutorial -title: Tutorial -head: [] -sidebar: - order: 2 -description: Create a React SPA with an API Worker using the Vite plugin ---- - -import { PackageManagers, WranglerConfig } from "~/components"; - -In this tutorial, you will create a React SPA that can be deployed as a Worker with Workers Assets. -You will then add an API Worker that can be accessed from the front-end code. -You will develop, build, and preview the application using Vite before finally deploying to Cloudflare. - -### Set up and configure the React SPA - -#### Scaffold a Vite project - -Start by creating a React TypeScript project with Vite. - - - -Open the `cloudflare-vite-tutorial` directory in your editor of choice. - -#### Add the Cloudflare dependencies - - - -#### Add the plugin to your Vite config - -```ts {5, 8} -// vite.config.ts - -import { defineConfig } from "vite"; -import react from "@vitejs/plugin-react"; -import { cloudflare } from "@cloudflare/vite-plugin"; - -export default defineConfig({ - plugins: [react(), cloudflare()], -}); -``` - -#### Create your Worker config file - - - -```toml -name = "cloudflare-vite-tutorial" -compatibility_date = "2024-12-30" -assets = { not_found_handling = "single-page-application" } -``` - - - -The [`not_found_handling`](/workers/static-assets/routing/#not_found_handling--404-page--single-page-application--none) value has been set to `single-page-application`. -This means that all not found requests will serve the `index.html` file. -With the Cloudflare plugin, the `assets` routing configuration is used in place of Vite's default behavior. -This ensures that your application's routing works the same way while developing as it does when deployed to production. - -Note that the [`directory`](/workers/static-assets/binding/#directory) field is not used when configuring assets with Vite. -The `directory` in the output configuration will automatically point to the client build output. - -:::note -When using the Cloudflare Vite plugin, the Worker config (for example, `wrangler.toml`) that you provide is the input configuration file. -A separate output `wrangler.json` file is created when you run `vite build`. -This output file is a snapshot of your configuration at the time of the build and is modified to reference your build artifacts. -It is the configuration that is used for preview and deployment. -::: - -#### Run the development server - -Run `npm run dev` to verify that your application is working as expected. - -For a purely front-end application, you could now build (`npm run build`), preview (`npm run preview`), and deploy (`npm exec wrangler deploy`) your application. -However, this tutorial will show you how to go a step further and add an API Worker. - -### Add an API Worker - -#### Configure TypeScript for your Worker code - - - -```jsonc -// tsconfig.worker.json - -{ - "extends": "./tsconfig.node.json", - "compilerOptions": { - "tsBuildInfoFile": "./node_modules/.tmp/tsconfig.worker.tsbuildinfo", - "types": ["@cloudflare/workers-types/2023-07-01", "vite/client"], - }, - "include": ["api"], -} -``` - -```jsonc {8} -// tsconfig.json - -{ - "files": [], - "references": [ - { "path": "./tsconfig.app.json" }, - { "path": "./tsconfig.node.json" }, - { "path": "./tsconfig.worker.json" }, - ], -} -``` - -#### Add to your Worker configuration - - - -```toml -name = "cloudflare-vite-tutorial" -compatibility_date = "2024-12-30" -assets = { not_found_handling = "single-page-application", binding = "ASSETS" } -main = "./api/index.ts" -``` - - - -The assets `binding` defined here will allow you to access the assets functionality from your Worker. - -#### Add your API Worker - -```ts -// api/index.ts - -interface Env { - ASSETS: Fetcher; -} - -export default { - fetch(request, env) { - const url = new URL(request.url); - - if (url.pathname.startsWith("/api/")) { - return Response.json({ - name: "Cloudflare", - }); - } - - return env.ASSETS.fetch(request); - }, -} satisfies ExportedHandler; -``` - -The Worker above will be invoked for any request not matching a static asset. -It returns a JSON response if the `pathname` starts with `/api/` and otherwise passes the incoming request through to the assets binding. -This means that for paths that do not start with `/api/`, the `not_found_handling` behavior defined in the Worker config will be evaluated and the `index.html` file will be returned, enabling SPA navigations. - -#### Call the API from the client - -Edit `src/App.tsx` so that it includes an additional button that calls the API and sets some state: - -```tsx {10, 34-48} collapse={14-29} -// src/App.tsx - -import { useState } from "react"; -import reactLogo from "./assets/react.svg"; -import viteLogo from "/vite.svg"; -import "./App.css"; - -function App() { - const [count, setCount] = useState(0); - const [name, setName] = useState("unknown"); - - return ( - <> - -

Vite + React

-
- -

- Edit src/App.tsx and save to test HMR -

-
-
- -

- Edit api/index.ts to change the name -

-
-

- Click on the Vite and React logos to learn more -

- - ); -} - -export default App; -``` - -Now, if you click the button, it will display 'Name from API is: Cloudflare'. - -Increment the counter to update the application state in the browser. -Next, edit `api/index.ts` by changing the `name` it returns to `'Cloudflare Workers'`. -If you click the button again, it will display the new `name` while preserving the previously set counter value. -With Vite and the Cloudflare plugin, you can iterate on the client and server parts of your app quickly without losing UI state between edits. - -#### Build your application - -Run `npm run build` to build your application. - -If you inspect the `dist` directory, you will see that it contains two subdirectories: `client` and `cloudflare-vite-tutorial`. -The `cloudflare-vite-tutorial` directory contains your Worker code and the output `wrangler.json` configuration. - -#### Preview your application - -Run `npm run preview` to validate that your application runs as expected. -This command will run your build output locally in the Workers runtime, closely matching its behaviour in production. - -#### Deploy to Cloudflare - -Run `npm exec wrangler deploy` to deploy your application to Cloudflare. -This command will automatically use the output `wrangler.json` that was included in the build output. - -### Next steps - -In this tutorial, we created an SPA that could be deployed as a Worker with Workers Assets. -We then added an API Worker that could be accessed from the front-end code and deployed to Cloudflare. -Possible next steps include: - -- Adding a binding to another Cloudflare service such as a [KV namespace](/kv/) or [D1 database](/d1/) -- Expanding the API to include additional routes -- Using a library, such as [tRPC](https://trpc.io/) or [Hono](https://hono.dev/), in your API Worker From c8d8eaddc336f89698b2643191a67cbffa9f16da Mon Sep 17 00:00:00 2001 From: korinne <40270578+korinne@users.noreply.github.com> Date: Fri, 7 Mar 2025 13:18:16 -0800 Subject: [PATCH 05/34] Update src/content/docs/workers/local-development/vite.mdx Co-authored-by: hyperlint-ai[bot] <154288675+hyperlint-ai[bot]@users.noreply.github.com> --- src/content/docs/workers/local-development/vite.mdx | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/content/docs/workers/local-development/vite.mdx b/src/content/docs/workers/local-development/vite.mdx index e987272d829cd68..fb0f7482b26f95f 100644 --- a/src/content/docs/workers/local-development/vite.mdx +++ b/src/content/docs/workers/local-development/vite.mdx @@ -27,7 +27,7 @@ If you are building anything that involves a front-end using [Workers static ass ## Get started -#### 1. Create your project directory and add a minimal package.json: +#### 1. Create your project directory and add a minimal package.JSON: ```json { From c2d590d23eba34fcc2088328ce77e1d4beb81f20 Mon Sep 17 00:00:00 2001 From: korinne <40270578+korinne@users.noreply.github.com> Date: Fri, 7 Mar 2025 13:18:27 -0800 Subject: [PATCH 06/34] Update src/content/docs/workers/local-development/wrangler.mdx Co-authored-by: hyperlint-ai[bot] <154288675+hyperlint-ai[bot]@users.noreply.github.com> --- src/content/docs/workers/local-development/wrangler.mdx | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/content/docs/workers/local-development/wrangler.mdx b/src/content/docs/workers/local-development/wrangler.mdx index 0a8b0c13dcc0549..63ef3d32e5d9c3b 100644 --- a/src/content/docs/workers/local-development/wrangler.mdx +++ b/src/content/docs/workers/local-development/wrangler.mdx @@ -43,7 +43,7 @@ npx wrangler dev | Queues | ✅ | ❌ | | R2 | ✅ | ✅ | | Rate Limiting | ✅ | ✅ | -| Service Bindings (multiple workers) | ✅ | ✅ | +| Service Bindings (multiple Workers) | ✅ | ✅ | | Vectorize | ✅[^2] | ✅ | | Workflows | ✅ | ❌ | From 87e01b5e612f4acf00de73bba2e4084ef2b91787 Mon Sep 17 00:00:00 2001 From: korinne Date: Fri, 7 Mar 2025 14:23:59 -0800 Subject: [PATCH 07/34] fix some broken links --- src/content/docs/workers/local-development/vite.mdx | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/content/docs/workers/local-development/vite.mdx b/src/content/docs/workers/local-development/vite.mdx index e987272d829cd68..a01f02174091f21 100644 --- a/src/content/docs/workers/local-development/vite.mdx +++ b/src/content/docs/workers/local-development/vite.mdx @@ -18,7 +18,7 @@ import { The Cloudflare Vite plugin (`@cloudflare/vite-plugin`) integrates your Worker code directly with [Vite](https://vite.dev/). Like `wrangler dev`, this approach uses `workerd` under the hood as well, and provides: -- Direct access to Workers [runtime APIs](/workers/runtime-apis/) and [bindings](/runtime-apis/bindings/) +- Direct access to Workers [runtime APIs](/workers/runtime-apis/) and [bindings](/workers/runtime-apis/bindings/) - [Hot module replacement (HMR)](https://vite.dev/guide/features.html#hot-module-replacement) for near-instant feedback on code changes. - A single workflow (`vite dev`, `vite build`, `vite preview`) that handles both your client-side assets and Worker code. - An “input” Wrangler config file and an automatically generated “output” config file (used for preview and deployment). @@ -214,7 +214,7 @@ vite build --mode staging ## Secrets in local development -Secrets can be provided to your Worker in local development using a [`.dev.vars`](/workers/configuration/secrets/#local-development-with-secrets) file. If you are using [Cloudflare Environments](../cloudflare-environments) then the relevant `.dev.vars` file will be selected. +Secrets can be provided to your Worker in local development using a [`.dev.vars`](/workers/configuration/secrets/#local-development-with-secrets) file. If you are using [Cloudflare Environments](#cloudflare-environments) then the relevant `.dev.vars` file will be selected. For example, @@ -230,7 +230,7 @@ When you run `vite build`, the relevant `.dev.vars[.env-name]` file is copied to ## Migrating from `wrangler dev` -Migrating from `wrangler dev` is a simple process and you can follow the instructions in [Get started](../get-started/). +Migrating from `wrangler dev` is a simple process and you can follow the instructions in [Get started](#get-started). There are a few key differences to highlight: From f6cf8a0056df8af7090f237bdc4e44eeda4aee15 Mon Sep 17 00:00:00 2001 From: korinne Date: Tue, 11 Mar 2025 16:01:47 -0700 Subject: [PATCH 08/34] =?UTF-8?q?consolidates=20current=20local=20dev=20do?= =?UTF-8?q?cs=20under=20new=20directory,=20and=20includes=20=20=E2=9B=85?= =?UTF-8?q?=EF=B8=8F=20wrangler=203.95.0=20(update=20available=203.114.1)?= =?UTF-8?q?=20----------------------------------------------=20in=20Overvi?= =?UTF-8?q?ew=20page?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../docs/workers/local-development.mdx | 141 ------------------ .../docs/workers/local-development/index.mdx | 4 +- 2 files changed, 2 insertions(+), 143 deletions(-) delete mode 100644 src/content/docs/workers/local-development.mdx diff --git a/src/content/docs/workers/local-development.mdx b/src/content/docs/workers/local-development.mdx deleted file mode 100644 index 92ba77458c4613a..000000000000000 --- a/src/content/docs/workers/local-development.mdx +++ /dev/null @@ -1,141 +0,0 @@ ---- -title: Local development -pcx_content_type: concept -sidebar: - order: 5 -head: [] -description: Develop your Workers locally via Wrangler. ---- - -Cloudflare Workers and most connected resources can be fully developed and tested locally - providing confidence that the applications you build locally will work the same way in production. This allows you to be more efficient and effective by providing a faster feedback loop and removing the need to [test against remote resources](#develop-using-remote-resources-and-bindings). Local development runs against the same production runtime used by Cloudflare Workers, [workerd](https://github.com/cloudflare/workerd). - -In addition to testing Workers locally with [`wrangler dev`](/workers/wrangler/commands/#dev), the use of Miniflare allows you to test other Developer Platform products locally, such as [R2](/r2/), [KV](/kv/), [D1](/d1/), and [Durable Objects](/durable-objects/). - -## Start a local development server - -:::note - -This guide assumes you are using [Wrangler v3.0](https://blog.cloudflare.com/wrangler3/) or later. - -Users new to Wrangler CLI and Cloudflare Workers should visit the [Wrangler Install/Update guide](/workers/wrangler/install-and-update) to install `wrangler`. - -::: - -Wrangler provides a [`dev`](/workers/wrangler/commands/#dev) command that starts a local server for developing your Worker. Make sure you have `npm` installed and run the following in the folder containing your Worker application: - -```sh -npx wrangler dev -``` - -`wrangler dev` will run the Worker directly on your local machine. `wrangler dev` uses a combination of `workerd` and [Miniflare](https://github.com/cloudflare/workers-sdk/tree/main/packages/miniflare), a simulator that allows you to test your Worker against additional resources like KV, Durable Objects, WebSockets, and more. - -### Supported resource bindings in different environments - -| Product | Local Dev Supported | Remote Dev Supported | -| ----------------------------------- | ------------------- | -------------------- | -| AI | ✅[^1] | ✅ | -| Assets | ✅ | ✅ | -| Analytics Engine | ✅ | ✅ | -| Browser Rendering | ❌ | ✅ | -| D1 | ✅ | ✅ | -| Durable Objects | ✅ | ✅ | -| Email Bindings | ❌ | ✅ | -| Hyperdrive | ✅ | ✅ | -| Images | ✅ | ✅ | -| KV | ✅ | ✅ | -| mTLS | ❌ | ✅ | -| Queues | ✅ | ❌ | -| R2 | ✅ | ✅ | -| Rate Limiting | ✅ | ✅ | -| Service Bindings (multiple workers) | ✅ | ✅ | -| Vectorize | ✅[^2] | ✅ | -| Workflows | ✅ | ❌ | - -With any bindings that are not supported locally, you will need to use the [`--remote` command](#develop-using-remote-resources-and-bindings) in wrangler, such as `wrangler dev --remote`. - -[^1]: Using Workers AI always accesses your Cloudflare account in order to run AI models and will incur usage charges even in local development. - -[^2]: Using Vectorize always accesses your Cloudflare account to run queries, and will incur usage charges even in local development. - -## Work with local data - -When running `wrangler dev`, resources such as KV, Durable Objects, D1, and R2 will be stored and persisted locally and not affect the production resources. - -### Use bindings in Wrangler configuration files - -[Wrangler](/workers/wrangler/) will automatically create local versions of bindings found in the [Wrangler configuration file](/workers/wrangler/configuration/). These local resources will not have data in them initially, so you will need to add data manually via Wrangler commands and the [`--local` flag](#use---local-flag). - -When you run `wrangler dev` Wrangler stores local resources in a `.wrangler/state` folder, which is automatically created. - -If you prefer to specify a directory, you can use the [`--persist-to`](/workers/wrangler/commands/#dev) flag with `wrangler dev` like this: - -```sh -npx wrangler dev --persist-to -``` - -Using this will write all local storage and cache to the specified directory instead of `.wrangler`. - -:::note - -This local persistence folder should be added to your `.gitignore` file. - -::: - -### Use `--local` flag - -The following [Wrangler commands](/workers/wrangler/commands/) have a `--local` flag which allows you to create, update, and delete local data during development: - -| Command | -| ---------------------------------------------------- | -| [`d1 execute`](/workers/wrangler/commands/#execute) | -| [`kv key`](/workers/wrangler/commands/#kv-key) | -| [`kv bulk`](/workers/wrangler/commands/#kv-bulk) | -| [`r2 object`](/workers/wrangler/commands/#r2-object) | - -If using `--persist-to` to specify a custom folder with `wrangler dev` you should also add `--persist-to` with the same directory name along with the `--local` flag when running the commands above. For example, to put a custom KV key into a local namespace via the CLI you would run: - -```sh -npx wrangler kv key put test 12345 --binding MY_KV_NAMESPACE --local --persist-to worker-local -``` - -Running `wrangler kv key put` will create a new key `test` with a value of `12345` on the local namespace specified via the binding `MY_KV_NAMESPACE` in the [Wrangler configuration file](/workers/wrangler/configuration/). This example command sets the local persistence directory to `worker-local` using `--persist-to`, to ensure that the data is created in the correct location. If `--persist-to` was not set, it would create the data in the `.wrangler` folder. - -### Clear Wrangler's local storage - -If you need to clear local storage entirely, delete the `.wrangler/state` folder. You can also be more fine-grained and delete specific resource folders within `.wrangler/state`. - -Any deleted folders will be created automatically the next time you run `wrangler dev`. - -## Local-only environment variables - -When running `wrangler dev`, variables in the [Wrangler configuration file](/workers/wrangler/configuration/) are automatically overridden by values defined in a `.dev.vars` file located in the root directory of your worker. This is useful for providing values you do not want to check in to source control. - -```shell -API_HOST = "localhost:4000" -API_ACCOUNT_ID = "local_example_user" -``` - -## Develop using remote resources and bindings - -There may be times you want to develop against remote resources and bindings. To run `wrangler dev` in remote mode, add the `--remote` flag, which will run both your code and resources remotely: - -```sh -npx wrangler dev --remote -``` - -For some products like KV and R2, remote resources used for `wrangler dev --remote` must be specified with preview ID/names in the [Wrangler configuration file](/workers/wrangler/configuration/) such as `preview_id` for KV or `preview_bucket name` for R2. Resources used for remote mode (preview) can be different from resources used for production to prevent changing production data during development. To use production data in `wrangler dev --remote`, set the preview ID/name of the resource to the ID/name of your production resource. - -## Customize `wrangler dev` - -You can customize how `wrangler dev` works to fit your needs. Refer to [the `wrangler dev` documentation](/workers/wrangler/commands/#dev) for available configuration options. - -:::caution - -There is a bug associated with how outgoing requests are handled when using `wrangler dev --remote`. For more information, read the [Known issues section](/workers/platform/known-issues/#wrangler-dev). - -::: - -## Related resources - -- [D1 local development](/d1/best-practices/local-development/) - The official D1 guide to local development and testing. -- [DevTools](/workers/observability/dev-tools) - Guides to using DevTools to debug your Worker locally. diff --git a/src/content/docs/workers/local-development/index.mdx b/src/content/docs/workers/local-development/index.mdx index 1e5d49ae1314deb..55d9fca004c604e 100644 --- a/src/content/docs/workers/local-development/index.mdx +++ b/src/content/docs/workers/local-development/index.mdx @@ -9,9 +9,9 @@ description: Develop your Workers locally. Cloudflare Workers provides two primary ways to develop and test your code locally. Local development ensures a fast feedback loop, keeps iteration times low, and lets you experiment before deploying to production. -Developers can locally test their changes to a Workers project using the following: +You can test changes locally using the following: -- **Wrangler’s built-in dev command** [`wrangler dev`](/workers/wrangler/commands/#dev), which uses [`workerd`](https://github.com/cloudflare/workerd) and Miniflare to simulate production behavior and resource bindings locally. +- **Wrangler’s built-in dev command** [`wrangler dev`](/workers/wrangler/commands/#dev), which uses [`workerd`](https://github.com/cloudflare/workerd) and Miniflare to simulate production behavior and resource bindings locally. Wrangler also offers the option to develop against remote resources with `wrangler dev --remote`, allowing you to test directly with data stored on Cloudflare's network. - The **Cloudflare Vite plugin** (`@cloudflare/vite-plugin`), which integrates directly with Vite and runs your code in the same `workerd` runtime, while also offering features like [hot module replacement (HMR)](https://vite.dev/guide/features.html#hot-module-replacement). The Vite plugin is currently considered in **beta**. From 22dd07e3552e071527b8190eea057acef99f254d Mon Sep 17 00:00:00 2001 From: korinne Date: Tue, 11 Mar 2025 16:30:23 -0700 Subject: [PATCH 09/34] Uses new PackageManager component in local-development/wrangler.mdx --- .../docs/workers/local-development/index.mdx | 4 +-- .../workers/local-development/wrangler.mdx | 26 ++++++++++--------- 2 files changed, 16 insertions(+), 14 deletions(-) diff --git a/src/content/docs/workers/local-development/index.mdx b/src/content/docs/workers/local-development/index.mdx index 55d9fca004c604e..3fe9b51c317a935 100644 --- a/src/content/docs/workers/local-development/index.mdx +++ b/src/content/docs/workers/local-development/index.mdx @@ -11,8 +11,8 @@ Cloudflare Workers provides two primary ways to develop and test your code local You can test changes locally using the following: -- **Wrangler’s built-in dev command** [`wrangler dev`](/workers/wrangler/commands/#dev), which uses [`workerd`](https://github.com/cloudflare/workerd) and Miniflare to simulate production behavior and resource bindings locally. Wrangler also offers the option to develop against remote resources with `wrangler dev --remote`, allowing you to test directly with data stored on Cloudflare's network. +- **Wrangler’s built-in dev command** [`wrangler dev`](/workers/wrangler/commands/#dev), which uses [`workerd`](https://github.com/cloudflare/workerd) and Miniflare to simulate production behavior and resource bindings locally. Wrangler also offers the option to [develop against remote resources](/workers/local-development/wrangler/#develop-using-remote-resources-and-bindings) with `wrangler dev --remote`, allowing you to test directly with data stored on Cloudflare's network. -- The **Cloudflare Vite plugin** (`@cloudflare/vite-plugin`), which integrates directly with Vite and runs your code in the same `workerd` runtime, while also offering features like [hot module replacement (HMR)](https://vite.dev/guide/features.html#hot-module-replacement). The Vite plugin is currently considered in **beta**. +- The **Cloudflare Vite plugin** (`@cloudflare/vite-plugin`), which integrates directly with [Vite](https://vite.dev/) and runs your code in the [Worker Runtime](/workers/reference/how-workers-works/) ([`workerd`](https://github.com/cloudflare/workerd)), while also offering features like [hot module replacement (HMR)](https://vite.dev/guide/features.html#hot-module-replacement). The Vite plugin is currently in open beta. Both approaches aim to provide confidence that your local environment will closely match the production runtime, removing the need to [test against remote resources](#develop-using-remote-resources-and-bindings). diff --git a/src/content/docs/workers/local-development/wrangler.mdx b/src/content/docs/workers/local-development/wrangler.mdx index 63ef3d32e5d9c3b..3c3d068e1d36562 100644 --- a/src/content/docs/workers/local-development/wrangler.mdx +++ b/src/content/docs/workers/local-development/wrangler.mdx @@ -7,6 +7,8 @@ head: [] description: Locally develop and test changes with `wrangler dev` --- +import { PackageManagers } from "~/components"; + ## Start a local development server :::note @@ -19,9 +21,7 @@ Users new to Wrangler CLI and Cloudflare Workers should visit the [Wrangler Inst Wrangler provides a [`dev`](/workers/wrangler/commands/#dev) command that starts a local server for developing your Worker. Make sure you have `npm` installed and run the following in the folder containing your Worker application: -```sh -npx wrangler dev -``` + `wrangler dev` will run the Worker directly on your local machine. `wrangler dev` uses a combination of `workerd` and [Miniflare](https://github.com/cloudflare/workers-sdk/tree/main/packages/miniflare), a simulator that allows you to test your Worker against additional resources like KV, Durable Objects, WebSockets, and more. @@ -65,9 +65,11 @@ When you run `wrangler dev` Wrangler stores local resources in a `.wrangler/stat If you prefer to specify a directory, you can use the [`--persist-to`](/workers/wrangler/commands/#dev) flag with `wrangler dev` like this: -```sh -npx wrangler dev --persist-to -``` + Using this will write all local storage and cache to the specified directory instead of `.wrangler`. @@ -90,9 +92,11 @@ The following [Wrangler commands](/workers/wrangler/commands/) have a `--local` If using `--persist-to` to specify a custom folder with `wrangler dev` you should also add `--persist-to` with the same directory name along with the `--local` flag when running the commands above. For example, to put a custom KV key into a local namespace via the CLI you would run: -```sh -npx wrangler kv key put test 12345 --binding MY_KV_NAMESPACE --local --persist-to worker-local -``` + Running `wrangler kv key put` will create a new key `test` with a value of `12345` on the local namespace specified via the binding `MY_KV_NAMESPACE` in the [Wrangler configuration file](/workers/wrangler/configuration/). This example command sets the local persistence directory to `worker-local` using `--persist-to`, to ensure that the data is created in the correct location. If `--persist-to` was not set, it would create the data in the `.wrangler` folder. @@ -115,9 +119,7 @@ API_ACCOUNT_ID = "local_example_user" There may be times you want to develop against remote resources and bindings. To run `wrangler dev` in remote mode, add the `--remote` flag, which will run both your code and resources remotely: -```sh -npx wrangler dev --remote -``` + For some products like KV and R2, remote resources used for `wrangler dev --remote` must be specified with preview ID/names in the [Wrangler configuration file](/workers/wrangler/configuration/) such as `preview_id` for KV or `preview_bucket name` for R2. Resources used for remote mode (preview) can be different from resources used for production to prevent changing production data during development. To use production data in `wrangler dev --remote`, set the preview ID/name of the resource to the ID/name of your production resource. From 66508f702122443302fd610a1768e72f94a0b0a6 Mon Sep 17 00:00:00 2001 From: korinne Date: Tue, 11 Mar 2025 16:46:49 -0700 Subject: [PATCH 10/34] adds bindings_per_env.mdx under src/content/partials/workers --- .../workers/local-development/wrangler.mdx | 30 ++---------------- .../partials/workers/bindings_per_env.mdx | 31 +++++++++++++++++++ 2 files changed, 33 insertions(+), 28 deletions(-) create mode 100644 src/content/partials/workers/bindings_per_env.mdx diff --git a/src/content/docs/workers/local-development/wrangler.mdx b/src/content/docs/workers/local-development/wrangler.mdx index 3c3d068e1d36562..3a4dd5ad1070619 100644 --- a/src/content/docs/workers/local-development/wrangler.mdx +++ b/src/content/docs/workers/local-development/wrangler.mdx @@ -7,7 +7,7 @@ head: [] description: Locally develop and test changes with `wrangler dev` --- -import { PackageManagers } from "~/components"; +import { Render, PackageManagers } from "~/components"; ## Start a local development server @@ -25,33 +25,7 @@ Wrangler provides a [`dev`](/workers/wrangler/commands/#dev) command that starts `wrangler dev` will run the Worker directly on your local machine. `wrangler dev` uses a combination of `workerd` and [Miniflare](https://github.com/cloudflare/workers-sdk/tree/main/packages/miniflare), a simulator that allows you to test your Worker against additional resources like KV, Durable Objects, WebSockets, and more. -### Supported resource bindings in different environments - -| Product | Local Dev Supported | Remote Dev Supported | -| ----------------------------------- | ------------------- | -------------------- | -| AI | ✅[^1] | ✅ | -| Assets | ✅ | ✅ | -| Analytics Engine | ✅ | ✅ | -| Browser Rendering | ❌ | ✅ | -| D1 | ✅ | ✅ | -| Durable Objects | ✅ | ✅ | -| Email Bindings | ❌ | ✅ | -| Hyperdrive | ✅ | ✅ | -| Images | ✅ | ✅ | -| KV | ✅ | ✅ | -| mTLS | ❌ | ✅ | -| Queues | ✅ | ❌ | -| R2 | ✅ | ✅ | -| Rate Limiting | ✅ | ✅ | -| Service Bindings (multiple Workers) | ✅ | ✅ | -| Vectorize | ✅[^2] | ✅ | -| Workflows | ✅ | ❌ | - -With any bindings that are not supported locally, you will need to use the [`--remote` command](#develop-using-remote-resources-and-bindings) in wrangler, such as `wrangler dev --remote`. - -[^1]: Using Workers AI always accesses your Cloudflare account in order to run AI models and will incur usage charges even in local development. - -[^2]: Using Vectorize always accesses your Cloudflare account to run queries, and will incur usage charges even in local development. + ## Work with local data diff --git a/src/content/partials/workers/bindings_per_env.mdx b/src/content/partials/workers/bindings_per_env.mdx new file mode 100644 index 000000000000000..90240e20b12a320 --- /dev/null +++ b/src/content/partials/workers/bindings_per_env.mdx @@ -0,0 +1,31 @@ +--- +{} +--- + +### Supported resource bindings in different environments + +| Product | Local Dev Supported | Remote Dev Supported | +| ----------------------------------- | ------------------- | -------------------- | +| AI | ✅[^1] | ✅ | +| Assets | ✅ | ✅ | +| Analytics Engine | ✅ | ✅ | +| Browser Rendering | ❌ | ✅ | +| D1 | ✅ | ✅ | +| Durable Objects | ✅ | ✅ | +| Email Bindings | ❌ | ✅ | +| Hyperdrive | ✅ | ✅ | +| Images | ✅ | ✅ | +| KV | ✅ | ✅ | +| mTLS | ❌ | ✅ | +| Queues | ✅ | ❌ | +| R2 | ✅ | ✅ | +| Rate Limiting | ✅ | ✅ | +| Service Bindings (multiple Workers) | ✅ | ✅ | +| Vectorize | ✅[^2] | ✅ | +| Workflows | ✅ | ❌ | + +With any bindings that are not supported locally, you will need to use the [`--remote` command](#develop-using-remote-resources-and-bindings) in wrangler, such as `wrangler dev --remote`. + +[^1]: Using Workers AI always accesses your Cloudflare account in order to run AI models and will incur usage charges even in local development. + +[^2]: Using Vectorize always accesses your Cloudflare account to run queries, and will incur usage charges even in local development. From 0c9b53d2aa9bf391921f4b5827a0bd38f53a2a44 Mon Sep 17 00:00:00 2001 From: korinne Date: Mon, 17 Mar 2025 06:00:50 -0700 Subject: [PATCH 11/34] Adds guidance for when to use Wrangler vs Vite, adds Vite to the binding comparison --- .../docs/workers/local-development/index.mdx | 22 +++++- .../workers/local-development/wrangler.mdx | 10 ++- .../partials/workers/bindings_per_env.mdx | 69 +++++++++++-------- 3 files changed, 70 insertions(+), 31 deletions(-) diff --git a/src/content/docs/workers/local-development/index.mdx b/src/content/docs/workers/local-development/index.mdx index 3fe9b51c317a935..d40b114cdcd0f89 100644 --- a/src/content/docs/workers/local-development/index.mdx +++ b/src/content/docs/workers/local-development/index.mdx @@ -13,6 +13,26 @@ You can test changes locally using the following: - **Wrangler’s built-in dev command** [`wrangler dev`](/workers/wrangler/commands/#dev), which uses [`workerd`](https://github.com/cloudflare/workerd) and Miniflare to simulate production behavior and resource bindings locally. Wrangler also offers the option to [develop against remote resources](/workers/local-development/wrangler/#develop-using-remote-resources-and-bindings) with `wrangler dev --remote`, allowing you to test directly with data stored on Cloudflare's network. -- The **Cloudflare Vite plugin** (`@cloudflare/vite-plugin`), which integrates directly with [Vite](https://vite.dev/) and runs your code in the [Worker Runtime](/workers/reference/how-workers-works/) ([`workerd`](https://github.com/cloudflare/workerd)), while also offering features like [hot module replacement (HMR)](https://vite.dev/guide/features.html#hot-module-replacement). The Vite plugin is currently in open beta. +- The **Cloudflare Vite plugin** (`@cloudflare/vite-plugin`), which integrates directly with [Vite](https://vite.dev/) and runs your code in the [Worker Runtime](/workers/reference/how-workers-works/) ([`workerd`](https://github.com/cloudflare/workerd)), while also offering features like [hot module replacement (HMR)](https://vite.dev/guide/features.html#hot-module-replacement). The Vite plugin is currently in **open beta**. Both approaches aim to provide confidence that your local environment will closely match the production runtime, removing the need to [test against remote resources](#develop-using-remote-resources-and-bindings). + +## Choosing Between Wrangler and the Vite Plugin + +When you are building with Cloudflare Workers, choosing between Wrangler and the Cloudflare Vite plugin primarily depends on your project’s scope and development workflow. Below are some guidelines to help you decide which toolset to use. + +### When to use Wrangler + +- **Backend and Workers-focused development:** Ideal if your primary goal is to build serverless functions, APIs, or other background tasks that need to closely resemble production behavior. Wrangler provides the most accurate local simulation of Cloudflare’s runtime. + +- **Testing with real Cloudflare resources:** If you need to verify interactions with actual Cloudflare data or services, Wrangler’s `--remote` flag lets you test in a production-like environment without deploying your app fully to production. + +- **Limited frontend requirements:** Wrangler is well suited for simple or minimal frontend needs, where complex bundling and advanced development features (like Hot Module Replacement) are not critical. + +### When to use the Cloudflare Vite Plugin + +- **Frontend-intensive developmentL** If your application relies heavily on modern frontend [frameworks](/workers/frameworks/) — such as React, Vue, Svelte, or Solid — the Vite plugin makes setup and configuration straightforward. + +- **Rapid iteration with HMR:** Hot Module Replacement (HMR) provides near-instant reloads whenever you make changes. This speeds up development by letting you see updates in the browser without a full page refresh. + +- **Advanced frontend optimizations**: The Vite plugin supports tree-shaking, code splitting, efficient bundling, CSS handling, and caching strategies. If you require optimized frontend delivery — especially for large or complex UIs — Vite is a strong fit. diff --git a/src/content/docs/workers/local-development/wrangler.mdx b/src/content/docs/workers/local-development/wrangler.mdx index 3a4dd5ad1070619..7628a5189bfa631 100644 --- a/src/content/docs/workers/local-development/wrangler.mdx +++ b/src/content/docs/workers/local-development/wrangler.mdx @@ -9,7 +9,7 @@ description: Locally develop and test changes with `wrangler dev` import { Render, PackageManagers } from "~/components"; -## Start a local development server +Wrangler provides a [`dev`](/workers/wrangler/commands/#dev) command that starts a local development server directly on your machine. It uses a combination of the Worker Runtime (`workerd`) and [Miniflare](https://github.com/cloudflare/workers-sdk/tree/main/packages/miniflare), a simulator that allows you to test your Worker against additional resources like [R2](/r2/), [KV](/kv), [D1](/d1), and [Durable Objects](/durable-objects). :::note @@ -19,11 +19,15 @@ Users new to Wrangler CLI and Cloudflare Workers should visit the [Wrangler Inst ::: -Wrangler provides a [`dev`](/workers/wrangler/commands/#dev) command that starts a local server for developing your Worker. Make sure you have `npm` installed and run the following in the folder containing your Worker application: +## Start a local development server + +To start a local development server for your Worker, navigate to your Worker’s project folder and run: -`wrangler dev` will run the Worker directly on your local machine. `wrangler dev` uses a combination of `workerd` and [Miniflare](https://github.com/cloudflare/workers-sdk/tree/main/packages/miniflare), a simulator that allows you to test your Worker against additional resources like KV, Durable Objects, WebSockets, and more. +This command runs your Worker code locally, allowing you to test changes in real time. By default, it will store local data in a `.wrangler/state` folder in your project directory. + +--- diff --git a/src/content/partials/workers/bindings_per_env.mdx b/src/content/partials/workers/bindings_per_env.mdx index 90240e20b12a320..98209faf42c1578 100644 --- a/src/content/partials/workers/bindings_per_env.mdx +++ b/src/content/partials/workers/bindings_per_env.mdx @@ -2,30 +2,45 @@ {} --- -### Supported resource bindings in different environments - -| Product | Local Dev Supported | Remote Dev Supported | -| ----------------------------------- | ------------------- | -------------------- | -| AI | ✅[^1] | ✅ | -| Assets | ✅ | ✅ | -| Analytics Engine | ✅ | ✅ | -| Browser Rendering | ❌ | ✅ | -| D1 | ✅ | ✅ | -| Durable Objects | ✅ | ✅ | -| Email Bindings | ❌ | ✅ | -| Hyperdrive | ✅ | ✅ | -| Images | ✅ | ✅ | -| KV | ✅ | ✅ | -| mTLS | ❌ | ✅ | -| Queues | ✅ | ❌ | -| R2 | ✅ | ✅ | -| Rate Limiting | ✅ | ✅ | -| Service Bindings (multiple Workers) | ✅ | ✅ | -| Vectorize | ✅[^2] | ✅ | -| Workflows | ✅ | ❌ | - -With any bindings that are not supported locally, you will need to use the [`--remote` command](#develop-using-remote-resources-and-bindings) in wrangler, such as `wrangler dev --remote`. - -[^1]: Using Workers AI always accesses your Cloudflare account in order to run AI models and will incur usage charges even in local development. - -[^2]: Using Vectorize always accesses your Cloudflare account to run queries, and will incur usage charges even in local development. +### Binding Support: Local vs. Remote Development + +#### Local Development + +Includes [Wrangler `dev`](/workers/wrangler/commands/#dev) without `--remote` and the [Cloudflare Vite plugin](/local-development/vite/). This mode simulates the Cloudflare Workers environment locally. + +#### Remote Development + +Uses [Wrangler `dev --remote`](/workers/wrangler/commands/#dev)), deploying your code to Cloudflare’s infrastructure during development. This ensures all bindings and resources match production conditions. + +| Binding | Local (Wrangler & Vite) | Remote (Wrangler only) | +| --------------------------------------- | :---------------------: | :--------------------: | +| **AI** | ✅¹ | ✅ | +| **Assets** | ✅ | ✅ | +| **Analytics Engine** | ✅ | ✅ | +| **Browser Rendering** | ❌ | ✅ | +| **D1** | ✅ | ✅ | +| **Durable Objects** | ✅ | ✅ | +| **Email Bindings** | ❌ | ✅ | +| **Hyperdrive** | ✅ | ✅ | +| **Images** | ✅ | ✅ | +| **KV** | ✅ | ✅ | +| **mTLS** | ❌ | ✅ | +| **Queues** | ✅ | ❌ | +| **R2** | ✅ | ✅ | +| **Rate Limiting** | ✅ | ✅ | +| **Service Bindings (multiple Workers)** | ✅ | ✅ | +| **Vectorize** | ✅² | ✅ | +| **Workflows** | ✅ | ❌ | + +¹ Using Workers AI always accesses your Cloudflare account to run AI models, incurring usage charges even during local development. +² Using Vectorize always accesses your Cloudflare account to run queries, incurring usage charges even during local development. + +> **Tip:** If you need to use any bindings marked with ❌ under local development, run: +> +> ```bash +> wrangler dev --remote +> ``` +> +> This uploads your code to Cloudflare so you can test those bindings against the real environment. + +--- From 547e15bb38a4c30689ad390dbf8a4f1e12f6f104 Mon Sep 17 00:00:00 2001 From: korinne Date: Mon, 17 Mar 2025 15:49:30 -0700 Subject: [PATCH 12/34] updates Wrangler local development guide, and partial for local vs remote dev --- .../workers/local-development/wrangler.mdx | 84 +++++++++++++------ .../partials/workers/bindings_per_env.mdx | 25 +++--- 2 files changed, 70 insertions(+), 39 deletions(-) diff --git a/src/content/docs/workers/local-development/wrangler.mdx b/src/content/docs/workers/local-development/wrangler.mdx index 7628a5189bfa631..d0eae2727e0c340 100644 --- a/src/content/docs/workers/local-development/wrangler.mdx +++ b/src/content/docs/workers/local-development/wrangler.mdx @@ -7,9 +7,11 @@ head: [] description: Locally develop and test changes with `wrangler dev` --- -import { Render, PackageManagers } from "~/components"; +import { Details, LinkCard, Render, PackageManagers } from "~/components"; -Wrangler provides a [`dev`](/workers/wrangler/commands/#dev) command that starts a local development server directly on your machine. It uses a combination of the Worker Runtime (`workerd`) and [Miniflare](https://github.com/cloudflare/workers-sdk/tree/main/packages/miniflare), a simulator that allows you to test your Worker against additional resources like [R2](/r2/), [KV](/kv), [D1](/d1), and [Durable Objects](/durable-objects). +## Local development with Wrangler + +The [Wrangler CLI](/workers/wrangler/) provides a [`dev`](/workers/wrangler/commands/#dev) command that starts a local development server directly on your machine. It uses a combination of the Workers Runtime (`workerd`) and [Miniflare](https://github.com/cloudflare/workers-sdk/tree/main/packages/miniflare), a simulator that allows you to test your Worker against additional resources like [R2](/r2/), [KV](/kv), [D1](/d1), and [Durable Objects](/durable-objects). :::note @@ -29,19 +31,21 @@ This command runs your Worker code locally, allowing you to test changes in real --- - +## Working with local data -## Work with local data +When you run `wrangler dev`, Wrangler automatically creates local versions of your resources (like KV, D1, or R2). This means you **don’t** need to manually set up separate local instances for each service. However, newly created local resources **won’t** contain any data — you'll need to use Wrangler commands with the `--local` flag to populate them. Changes made to local resources won’t affect production data. -When running `wrangler dev`, resources such as KV, Durable Objects, D1, and R2 will be stored and persisted locally and not affect the production resources. +By default, local data resides in the `.wrangler/state` folder. You can delete this folder at any time to reset your local environment, and Wrangler will recreate it the next time you run `wrangler dev`. -### Use bindings in Wrangler configuration files + -When you run `wrangler dev` Wrangler stores local resources in a `.wrangler/state` folder, which is automatically created. +### Changing the local data directory -If you prefer to specify a directory, you can use the [`--persist-to`](/workers/wrangler/commands/#dev) flag with `wrangler dev` like this: +If you prefer to specify a different directory for local storage, use the [`--persist-to`](/workers/wrangler/commands/#dev) flag with `wrangler dev`: -Using this will write all local storage and cache to the specified directory instead of `.wrangler`. - :::note - -This local persistence folder should be added to your `.gitignore` file. +The local persistence folder (like `.wrangler/state` or any custom folder you set) should be added to your `.gitignore` to avoid committing local development data to version control. ::: -### Use `--local` flag +### Using the `--local` flag The following [Wrangler commands](/workers/wrangler/commands/) have a `--local` flag which allows you to create, update, and delete local data during development: @@ -68,7 +69,10 @@ The following [Wrangler commands](/workers/wrangler/commands/) have a `--local` | [`kv bulk`](/workers/wrangler/commands/#kv-bulk) | | [`r2 object`](/workers/wrangler/commands/#r2-object) | -If using `--persist-to` to specify a custom folder with `wrangler dev` you should also add `--persist-to` with the same directory name along with the `--local` flag when running the commands above. For example, to put a custom KV key into a local namespace via the CLI you would run: +
+If you run `wrangler dev --persist-to ` to specify a custom location for local data, you must also include the same `--persist-to ` when running other Wrangler commands that modify local data (and be sure to include the `--local` flag). + +For example, to create a KV key named `test` with a value of `12345` in a local KV namespace, run: -Running `wrangler kv key put` will create a new key `test` with a value of `12345` on the local namespace specified via the binding `MY_KV_NAMESPACE` in the [Wrangler configuration file](/workers/wrangler/configuration/). This example command sets the local persistence directory to `worker-local` using `--persist-to`, to ensure that the data is created in the correct location. If `--persist-to` was not set, it would create the data in the `.wrangler` folder. +This command: + +- Sets the KV key `test` to `12345` in the binding `MY_KV_NAMESPACE` (defined in your [Wrangler configuration file](/workers/wrangler/configuration/)). +- Uses `--persist-to worker-local` to ensure the data is created in the **worker-local** directory instead of the default `.wrangler/state`. +- Adds the `--local` flag, indicating you want to modify local data. + +If `--persist-to` is not specified, Wrangler defaults to using `.wrangler/state` for local data. + +
### Clear Wrangler's local storage -If you need to clear local storage entirely, delete the `.wrangler/state` folder. You can also be more fine-grained and delete specific resource folders within `.wrangler/state`. +To reset or remove local storage: + +- Delete the entire `.wrangler/state` folder, or +- Delete specific sub-folders within `.wrangler/state` for more targeted clean-up. -Any deleted folders will be created automatically the next time you run `wrangler dev`. +Any folders you remove will be automatically re-created the next time you run `wrangler dev`. -## Local-only environment variables +### Local-only secrets and environment variables -When running `wrangler dev`, variables in the [Wrangler configuration file](/workers/wrangler/configuration/) are automatically overridden by values defined in a `.dev.vars` file located in the root directory of your worker. This is useful for providing values you do not want to check in to source control. +The [`.dev.vars` file](/workers/configuration/secrets/#local-development-with-secrets) is primarily intended for defining **local secrets** that you do not want to commit to source control. Any environment variables declared in `.dev.vars` will override matching variables in your [Wrangler configuration file](/workers/wrangler/configuration/) **when running `wrangler dev`**. + +For example, if you want to test local credentials or mock a production API endpoint: ```shell -API_HOST = "localhost:4000" -API_ACCOUNT_ID = "local_example_user" +API_HOST="localhost:4000" +API_ACCOUNT_ID="local_example_user" ``` -## Develop using remote resources and bindings +:::note +Since `.dev.vars` is loaded only when running `wrangler dev`, these values do not affect your production environment. Make sure to add `.dev.vars` to your `.gitignore` so you don’t accidentally commit sensitive credentials to version control. +::: + +To learn about setting up environment variables for other non-local environments (such as staging or production), look into [Wrangler Environments](/wrangler/environments/#staging-and-production-environments). + +## Working with remote data -There may be times you want to develop against remote resources and bindings. To run `wrangler dev` in remote mode, add the `--remote` flag, which will run both your code and resources remotely: +Sometimes you need to test your Worker against real Cloudflare resources (for example, to ensure accurate data or environment parity). In this case, use the `wrangler dev --remote` command: -For some products like KV and R2, remote resources used for `wrangler dev --remote` must be specified with preview ID/names in the [Wrangler configuration file](/workers/wrangler/configuration/) such as `preview_id` for KV or `preview_bucket name` for R2. Resources used for remote mode (preview) can be different from resources used for production to prevent changing production data during development. To use production data in `wrangler dev --remote`, set the preview ID/name of the resource to the ID/name of your production resource. +### Preview vs. Production Resources + +For certain services, like KV and R2, **remote** development (`wrangler dev --remote`) requires specifying **preview** IDs or names in your [Wrangler configuration file](/workers/wrangler/configuration/). For example: + +- KV uses `preview_id` +- R2 uses `preview_bucket` + +By default, these **preview** resources can be different from your production resources, letting you develop safely without modifying live data. If you do need to work with production data while using `wrangler dev --remote`, simply set the preview ID or name to match your production resource’s ID or name. + + ## Customize `wrangler dev` -You can customize how `wrangler dev` works to fit your needs. Refer to [the `wrangler dev` documentation](/workers/wrangler/commands/#dev) for available configuration options. +You can further customize the behavior of `wrangler dev` (for instance, by changing ports or skipping Wrangler's build steps). Refer to [the `wrangler dev` documentation](/workers/wrangler/commands/#dev) for available configuration options. :::caution diff --git a/src/content/partials/workers/bindings_per_env.mdx b/src/content/partials/workers/bindings_per_env.mdx index 98209faf42c1578..e769fb4c176056a 100644 --- a/src/content/partials/workers/bindings_per_env.mdx +++ b/src/content/partials/workers/bindings_per_env.mdx @@ -2,26 +2,22 @@ {} --- -### Binding Support: Local vs. Remote Development +## Supported bindings in local and remote dev -#### Local Development +- **Local Development:** Includes [`wrangler dev`](/workers/wrangler/commands/#dev) (without the `--remote` flag) and the [Cloudflare Vite plugin](/local-development/vite/). This mode simulates the Cloudflare Workers environment locally. -Includes [Wrangler `dev`](/workers/wrangler/commands/#dev) without `--remote` and the [Cloudflare Vite plugin](/local-development/vite/). This mode simulates the Cloudflare Workers environment locally. - -#### Remote Development - -Uses [Wrangler `dev --remote`](/workers/wrangler/commands/#dev)), deploying your code to Cloudflare’s infrastructure during development. This ensures all bindings and resources match production conditions. +- **Remote Development:** Uses [`wrangler dev --remote`](/workers/wrangler/commands/#dev)), deploying your code to Cloudflare’s infrastructure during development. This ensures all bindings and resources match production conditions. There is no Vite plugin equivalent for testing remote resources. | Binding | Local (Wrangler & Vite) | Remote (Wrangler only) | | --------------------------------------- | :---------------------: | :--------------------: | -| **AI** | ✅¹ | ✅ | +| **AI** | ✅[^1] | ✅ | | **Assets** | ✅ | ✅ | | **Analytics Engine** | ✅ | ✅ | | **Browser Rendering** | ❌ | ✅ | | **D1** | ✅ | ✅ | | **Durable Objects** | ✅ | ✅ | | **Email Bindings** | ❌ | ✅ | -| **Hyperdrive** | ✅ | ✅ | +| **Hyperdrive** | ✅[^2] | ✅ | | **Images** | ✅ | ✅ | | **KV** | ✅ | ✅ | | **mTLS** | ❌ | ✅ | @@ -29,11 +25,14 @@ Uses [Wrangler `dev --remote`](/workers/wrangler/commands/#dev)), deploying your | **R2** | ✅ | ✅ | | **Rate Limiting** | ✅ | ✅ | | **Service Bindings (multiple Workers)** | ✅ | ✅ | -| **Vectorize** | ✅² | ✅ | +| **Vectorize** | ✅[^3] | ✅ | | **Workflows** | ✅ | ❌ | -¹ Using Workers AI always accesses your Cloudflare account to run AI models, incurring usage charges even during local development. -² Using Vectorize always accesses your Cloudflare account to run queries, incurring usage charges even during local development. +[^1]: Using Workers AI always accesses your Cloudflare account in order to run AI models and will incur usage charges, even in local development. + +[^2]: Using Hyperdrive with local development allows you to connect to a local database (running on `localhost`) but you cannot connect to a remote database. To connect to a remote database, use `wrangler dev --remote`. + +[^3]: Using Vectorize always accesses your Cloudflare account to run queries, and will incur usage charges even in local development. > **Tip:** If you need to use any bindings marked with ❌ under local development, run: > @@ -41,6 +40,6 @@ Uses [Wrangler `dev --remote`](/workers/wrangler/commands/#dev)), deploying your > wrangler dev --remote > ``` > -> This uploads your code to Cloudflare so you can test those bindings against the real environment. +> This command allows you to develop against remote resources and data stored on Cloudflare's network. --- From 69b09ffc777fd6b4812c74a87da297341a1a1614 Mon Sep 17 00:00:00 2001 From: korinne Date: Mon, 17 Mar 2025 16:00:00 -0700 Subject: [PATCH 13/34] updates overview page to make more concise --- .../docs/workers/local-development/index.mdx | 26 ++++++++++++------- .../docs/workers/local-development/vite.mdx | 2 ++ 2 files changed, 18 insertions(+), 10 deletions(-) diff --git a/src/content/docs/workers/local-development/index.mdx b/src/content/docs/workers/local-development/index.mdx index d40b114cdcd0f89..98b1348ea52accb 100644 --- a/src/content/docs/workers/local-development/index.mdx +++ b/src/content/docs/workers/local-development/index.mdx @@ -17,22 +17,28 @@ You can test changes locally using the following: Both approaches aim to provide confidence that your local environment will closely match the production runtime, removing the need to [test against remote resources](#develop-using-remote-resources-and-bindings). -## Choosing Between Wrangler and the Vite Plugin +## Choosing Between Wrangler and Vite -When you are building with Cloudflare Workers, choosing between Wrangler and the Cloudflare Vite plugin primarily depends on your project’s scope and development workflow. Below are some guidelines to help you decide which toolset to use. +Deciding between Wrangler and the Cloudflare Vite plugin depends on your project's focus and development workflow. Here are some quick guidelines to help you choose: -### When to use Wrangler +### When to use Wrangler: -- **Backend and Workers-focused development:** Ideal if your primary goal is to build serverless functions, APIs, or other background tasks that need to closely resemble production behavior. Wrangler provides the most accurate local simulation of Cloudflare’s runtime. +- **Backend & Workers-focused:** + If you're primarily building APIs, serverless functions, or background tasks that need to closely match production behavior, use Wrangler. Wrangler offers the most accurate local simulation of Cloudflare’s runtime. -- **Testing with real Cloudflare resources:** If you need to verify interactions with actual Cloudflare data or services, Wrangler’s `--remote` flag lets you test in a production-like environment without deploying your app fully to production. +- **Real Cloudflare resources:** + Need to test actual Cloudflare data or services? Wrangler’s `--remote` flag lets you do so without fully deploying to production. -- **Limited frontend requirements:** Wrangler is well suited for simple or minimal frontend needs, where complex bundling and advanced development features (like Hot Module Replacement) are not critical. +- **Simple frontends:** + If you have minimal frontend requirements and don’t need hot reloading or advanced bundling, Wrangler by itself is sufficient. -### When to use the Cloudflare Vite Plugin +### When to use the Cloudflare Vite Plugin: -- **Frontend-intensive developmentL** If your application relies heavily on modern frontend [frameworks](/workers/frameworks/) — such as React, Vue, Svelte, or Solid — the Vite plugin makes setup and configuration straightforward. +- **Frontend-centric development:** + If you rely on modern frameworks like React, Vue, Svelte, or Solid, the Vite plugin simplifies setup and integration. -- **Rapid iteration with HMR:** Hot Module Replacement (HMR) provides near-instant reloads whenever you make changes. This speeds up development by letting you see updates in the browser without a full page refresh. +- **Rapid iteration (HMR):** + If you need near-instant updates in the browser, the Vite plugin provides Hot Module Replacement (HMR) during local development. -- **Advanced frontend optimizations**: The Vite plugin supports tree-shaking, code splitting, efficient bundling, CSS handling, and caching strategies. If you require optimized frontend delivery — especially for large or complex UIs — Vite is a strong fit. +- **Advanced optimizations:** + If you require more advanced optimizations (tree-shaking, code splitting, efficient bundling, CSS handling, etc), Vite is a strong fit. diff --git a/src/content/docs/workers/local-development/vite.mdx b/src/content/docs/workers/local-development/vite.mdx index 8d0087131440989..83c4c6cc64833f0 100644 --- a/src/content/docs/workers/local-development/vite.mdx +++ b/src/content/docs/workers/local-development/vite.mdx @@ -16,6 +16,8 @@ import { WranglerConfig, } from "~/components"; +## Local development with Vite + The Cloudflare Vite plugin (`@cloudflare/vite-plugin`) integrates your Worker code directly with [Vite](https://vite.dev/). Like `wrangler dev`, this approach uses `workerd` under the hood as well, and provides: - Direct access to Workers [runtime APIs](/workers/runtime-apis/) and [bindings](/workers/runtime-apis/bindings/) From 15560288f86541b42ca11e2cbb65fe2c3f4fd004 Mon Sep 17 00:00:00 2001 From: korinne Date: Tue, 18 Mar 2025 10:07:37 -0700 Subject: [PATCH 14/34] fixes broken links --- src/content/docs/workers/local-development/wrangler.mdx | 2 +- src/content/partials/workers/bindings_per_env.mdx | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/src/content/docs/workers/local-development/wrangler.mdx b/src/content/docs/workers/local-development/wrangler.mdx index d0eae2727e0c340..6d8e6e4805d59cc 100644 --- a/src/content/docs/workers/local-development/wrangler.mdx +++ b/src/content/docs/workers/local-development/wrangler.mdx @@ -114,7 +114,7 @@ API_ACCOUNT_ID="local_example_user" Since `.dev.vars` is loaded only when running `wrangler dev`, these values do not affect your production environment. Make sure to add `.dev.vars` to your `.gitignore` so you don’t accidentally commit sensitive credentials to version control. ::: -To learn about setting up environment variables for other non-local environments (such as staging or production), look into [Wrangler Environments](/wrangler/environments/#staging-and-production-environments). +To learn about setting up environment variables for other non-local environments (such as staging or production), look into [Wrangler Environments](/workers/wrangler/environments/#staging-and-production-environments). ## Working with remote data diff --git a/src/content/partials/workers/bindings_per_env.mdx b/src/content/partials/workers/bindings_per_env.mdx index e769fb4c176056a..b6d65308f21e5cf 100644 --- a/src/content/partials/workers/bindings_per_env.mdx +++ b/src/content/partials/workers/bindings_per_env.mdx @@ -4,7 +4,7 @@ ## Supported bindings in local and remote dev -- **Local Development:** Includes [`wrangler dev`](/workers/wrangler/commands/#dev) (without the `--remote` flag) and the [Cloudflare Vite plugin](/local-development/vite/). This mode simulates the Cloudflare Workers environment locally. +- **Local Development:** Includes [`wrangler dev`](/workers/wrangler/commands/#dev) (without the `--remote` flag) and the [Cloudflare Vite plugin](/workers/local-development/vite/). This mode simulates the Cloudflare Workers environment locally. - **Remote Development:** Uses [`wrangler dev --remote`](/workers/wrangler/commands/#dev)), deploying your code to Cloudflare’s infrastructure during development. This ensures all bindings and resources match production conditions. There is no Vite plugin equivalent for testing remote resources. From ac90adca050edbc1221e9a4dfc979049eadd3a2c Mon Sep 17 00:00:00 2001 From: korinne <40270578+korinne@users.noreply.github.com> Date: Wed, 19 Mar 2025 12:05:42 -0700 Subject: [PATCH 15/34] Update src/content/docs/workers/local-development/vite.mdx Co-authored-by: James Opstad <13586373+jamesopstad@users.noreply.github.com> --- src/content/docs/workers/local-development/vite.mdx | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/content/docs/workers/local-development/vite.mdx b/src/content/docs/workers/local-development/vite.mdx index 83c4c6cc64833f0..dc36e4e72793074 100644 --- a/src/content/docs/workers/local-development/vite.mdx +++ b/src/content/docs/workers/local-development/vite.mdx @@ -224,7 +224,7 @@ For example, CLOUDFLARE_ENV=staging vite dev ``` -Will load `.dev.vars.staging` if it exists (falling back to `.dev.vars` if otherwise). +Will load `.dev.vars.staging` if it exists and otherwise fall back to `.dev.vars`. :::note When you run `vite build`, the relevant `.dev.vars[.env-name]` file is copied to the output directory for use during `vite preview`. It is **not** deployed with your Worker. From 2dfae73a8203109ed965af195824c702b1fe84f2 Mon Sep 17 00:00:00 2001 From: korinne <40270578+korinne@users.noreply.github.com> Date: Wed, 19 Mar 2025 12:06:04 -0700 Subject: [PATCH 16/34] Update src/content/docs/workers/local-development/vite.mdx Co-authored-by: James Opstad <13586373+jamesopstad@users.noreply.github.com> --- src/content/docs/workers/local-development/vite.mdx | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/content/docs/workers/local-development/vite.mdx b/src/content/docs/workers/local-development/vite.mdx index dc36e4e72793074..cf847385d762d20 100644 --- a/src/content/docs/workers/local-development/vite.mdx +++ b/src/content/docs/workers/local-development/vite.mdx @@ -96,7 +96,7 @@ export default { npm run dev ``` -This starts a local development server, using the Workers runtime behind the scenes. You can build (`npm run build)`, preview (`npm run preview`), or deploy (`npm exec wrangler deploy`) at any time. +This starts a local development server, using the Workers runtime behind the scenes. When you are ready, you can build (`npm run build)`, preview (`npm run preview`), and deploy (`npm exec wrangler deploy`) your application. ## Cloudflare environments From df198766480a5f3c6104e6c687bf591702954061 Mon Sep 17 00:00:00 2001 From: korinne <40270578+korinne@users.noreply.github.com> Date: Wed, 19 Mar 2025 12:06:13 -0700 Subject: [PATCH 17/34] Update src/content/docs/workers/local-development/vite.mdx Co-authored-by: James Opstad <13586373+jamesopstad@users.noreply.github.com> --- src/content/docs/workers/local-development/vite.mdx | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/content/docs/workers/local-development/vite.mdx b/src/content/docs/workers/local-development/vite.mdx index cf847385d762d20..52fbd37fe901684 100644 --- a/src/content/docs/workers/local-development/vite.mdx +++ b/src/content/docs/workers/local-development/vite.mdx @@ -22,7 +22,7 @@ The Cloudflare Vite plugin (`@cloudflare/vite-plugin`) integrates your Worker co - Direct access to Workers [runtime APIs](/workers/runtime-apis/) and [bindings](/workers/runtime-apis/bindings/) - [Hot module replacement (HMR)](https://vite.dev/guide/features.html#hot-module-replacement) for near-instant feedback on code changes. -- A single workflow (`vite dev`, `vite build`, `vite preview`) that handles both your client-side assets and Worker code. +- A single workflow (`vite dev`, `vite build`, `vite preview`) that handles both your client-side and Worker code. - An “input” Wrangler config file and an automatically generated “output” config file (used for preview and deployment). If you are building anything that involves a front-end using [Workers static assets](/workers/static-assets/), the Vite approach can be particularly powerful. From 9d5202c22cef51bdf0334f2bab319ecde52e97d9 Mon Sep 17 00:00:00 2001 From: korinne <40270578+korinne@users.noreply.github.com> Date: Wed, 19 Mar 2025 12:06:47 -0700 Subject: [PATCH 18/34] Update src/content/docs/workers/local-development/index.mdx Co-authored-by: James Opstad <13586373+jamesopstad@users.noreply.github.com> --- src/content/docs/workers/local-development/index.mdx | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/content/docs/workers/local-development/index.mdx b/src/content/docs/workers/local-development/index.mdx index 98b1348ea52accb..aa3f9b720fcddce 100644 --- a/src/content/docs/workers/local-development/index.mdx +++ b/src/content/docs/workers/local-development/index.mdx @@ -11,9 +11,9 @@ Cloudflare Workers provides two primary ways to develop and test your code local You can test changes locally using the following: -- **Wrangler’s built-in dev command** [`wrangler dev`](/workers/wrangler/commands/#dev), which uses [`workerd`](https://github.com/cloudflare/workerd) and Miniflare to simulate production behavior and resource bindings locally. Wrangler also offers the option to [develop against remote resources](/workers/local-development/wrangler/#develop-using-remote-resources-and-bindings) with `wrangler dev --remote`, allowing you to test directly with data stored on Cloudflare's network. +- **Wrangler’s built-in dev command** [`wrangler dev`](/workers/wrangler/commands/#dev), which runs your code in the [Workers Runtime](/workers/reference/how-workers-works/) ([`workerd`](https://github.com/cloudflare/workerd)) to simulate production behavior and resource bindings locally. Wrangler also offers the option to [develop against remote resources](/workers/local-development/wrangler/#develop-using-remote-resources-and-bindings) with `wrangler dev --remote`, allowing you to test directly with data stored on Cloudflare's network. -- The **Cloudflare Vite plugin** (`@cloudflare/vite-plugin`), which integrates directly with [Vite](https://vite.dev/) and runs your code in the [Worker Runtime](/workers/reference/how-workers-works/) ([`workerd`](https://github.com/cloudflare/workerd)), while also offering features like [hot module replacement (HMR)](https://vite.dev/guide/features.html#hot-module-replacement). The Vite plugin is currently in **open beta**. +- The **Cloudflare Vite plugin** (`@cloudflare/vite-plugin`), which integrates directly with [Vite](https://vite.dev/) and runs your code in the [Workers Runtime](/workers/reference/how-workers-works/) ([`workerd`](https://github.com/cloudflare/workerd)) to simulate production behavior and resource bindings locally. The Vite plugin also offers features like [hot module replacement (HMR)](https://vite.dev/guide/features.html#hot-module-replacement) and access to Vite's ecosystem and build time transformations. It is currently in **open beta**. Both approaches aim to provide confidence that your local environment will closely match the production runtime, removing the need to [test against remote resources](#develop-using-remote-resources-and-bindings). From 64875a96f0abfa3e298ddb6ac1e9c23764a1a3dc Mon Sep 17 00:00:00 2001 From: korinne Date: Fri, 28 Mar 2025 16:41:02 -0700 Subject: [PATCH 19/34] moves local development section nearer to testing section --- src/content/docs/workers/local-development.mdx | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/content/docs/workers/local-development.mdx b/src/content/docs/workers/local-development.mdx index 5403c66c1bb2dd1..8a2396e61731c19 100644 --- a/src/content/docs/workers/local-development.mdx +++ b/src/content/docs/workers/local-development.mdx @@ -2,7 +2,7 @@ title: Local development pcx_content_type: concept sidebar: - order: 5 + order: 14 head: [] description: Develop your Workers locally via Wrangler. --- From 57de775d35a4c35734a3868c2c5fbbbc940ddb02 Mon Sep 17 00:00:00 2001 From: korinne Date: Tue, 1 Apr 2025 21:40:14 -0700 Subject: [PATCH 20/34] cleans up text in choosing between wrangler and vite --- src/content/docs/workers/local-development/index.mdx | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/content/docs/workers/local-development/index.mdx b/src/content/docs/workers/local-development/index.mdx index aa3f9b720fcddce..13ad7485ebee9ac 100644 --- a/src/content/docs/workers/local-development/index.mdx +++ b/src/content/docs/workers/local-development/index.mdx @@ -24,7 +24,7 @@ Deciding between Wrangler and the Cloudflare Vite plugin depends on your project ### When to use Wrangler: - **Backend & Workers-focused:** - If you're primarily building APIs, serverless functions, or background tasks that need to closely match production behavior, use Wrangler. Wrangler offers the most accurate local simulation of Cloudflare’s runtime. + If you're primarily building APIs, serverless functions, or background tasks that need to closely match production behavior, use Wrangler. - **Real Cloudflare resources:** Need to test actual Cloudflare data or services? Wrangler’s `--remote` flag lets you do so without fully deploying to production. From 9aaeb9ca8aabaf342a8223d913154aa67a13f9a6 Mon Sep 17 00:00:00 2001 From: korinne Date: Tue, 1 Apr 2025 21:50:26 -0700 Subject: [PATCH 21/34] updates overview page for local development --- src/content/docs/workers/local-development/index.mdx | 12 +++++------- 1 file changed, 5 insertions(+), 7 deletions(-) diff --git a/src/content/docs/workers/local-development/index.mdx b/src/content/docs/workers/local-development/index.mdx index 13ad7485ebee9ac..85805edc0e1115f 100644 --- a/src/content/docs/workers/local-development/index.mdx +++ b/src/content/docs/workers/local-development/index.mdx @@ -15,24 +15,22 @@ You can test changes locally using the following: - The **Cloudflare Vite plugin** (`@cloudflare/vite-plugin`), which integrates directly with [Vite](https://vite.dev/) and runs your code in the [Workers Runtime](/workers/reference/how-workers-works/) ([`workerd`](https://github.com/cloudflare/workerd)) to simulate production behavior and resource bindings locally. The Vite plugin also offers features like [hot module replacement (HMR)](https://vite.dev/guide/features.html#hot-module-replacement) and access to Vite's ecosystem and build time transformations. It is currently in **open beta**. -Both approaches aim to provide confidence that your local environment will closely match the production runtime, removing the need to [test against remote resources](#develop-using-remote-resources-and-bindings). - ## Choosing Between Wrangler and Vite Deciding between Wrangler and the Cloudflare Vite plugin depends on your project's focus and development workflow. Here are some quick guidelines to help you choose: -### When to use Wrangler: +### When to use Wrangler - **Backend & Workers-focused:** If you're primarily building APIs, serverless functions, or background tasks that need to closely match production behavior, use Wrangler. -- **Real Cloudflare resources:** - Need to test actual Cloudflare data or services? Wrangler’s `--remote` flag lets you do so without fully deploying to production. +- **Remote development:** + If your project needs the ability to develop and test using production resources and data, use Wrangler's `--remote` flag. - **Simple frontends:** If you have minimal frontend requirements and don’t need hot reloading or advanced bundling, Wrangler by itself is sufficient. -### When to use the Cloudflare Vite Plugin: +### When to use the Cloudflare Vite Plugin - **Frontend-centric development:** If you rely on modern frameworks like React, Vue, Svelte, or Solid, the Vite plugin simplifies setup and integration. @@ -41,4 +39,4 @@ Deciding between Wrangler and the Cloudflare Vite plugin depends on your project If you need near-instant updates in the browser, the Vite plugin provides Hot Module Replacement (HMR) during local development. - **Advanced optimizations:** - If you require more advanced optimizations (tree-shaking, code splitting, efficient bundling, CSS handling, etc), Vite is a strong fit. + If you require more advanced optimizations (code splitting, efficient bundling, CSS handling, etc), Vite is a strong fit. From 7b3f8583b2978665cebdd4e0dc963d1eca20ce3b Mon Sep 17 00:00:00 2001 From: korinne Date: Fri, 4 Apr 2025 10:22:47 -0700 Subject: [PATCH 22/34] update overview page, add working with data page --- .../docs/workers/local-development/index.mdx | 17 ++- .../local-development/working-with-data.mdx | 131 ++++++++++++++++++ .../workers/local-development/wrangler.mdx | 117 ---------------- 3 files changed, 139 insertions(+), 126 deletions(-) create mode 100644 src/content/docs/workers/local-development/working-with-data.mdx diff --git a/src/content/docs/workers/local-development/index.mdx b/src/content/docs/workers/local-development/index.mdx index 85805edc0e1115f..44a8392bcaa4284 100644 --- a/src/content/docs/workers/local-development/index.mdx +++ b/src/content/docs/workers/local-development/index.mdx @@ -7,13 +7,12 @@ head: [] description: Develop your Workers locally. --- -Cloudflare Workers provides two primary ways to develop and test your code locally. Local development ensures a fast feedback loop, keeps iteration times low, and lets you experiment before deploying to production. +When building projects on Cloudflare Workers, you have two options for local development: -You can test changes locally using the following: +- [**Wrangler**](/workers/wrangler/), using the built-in [`wrangler dev`](/workers/wrangler/commands/#dev) command. +- [Vite](https://vite.dev/), using the [**Cloudflare Vite plugin**](/workers/vite-plugin/). -- **Wrangler’s built-in dev command** [`wrangler dev`](/workers/wrangler/commands/#dev), which runs your code in the [Workers Runtime](/workers/reference/how-workers-works/) ([`workerd`](https://github.com/cloudflare/workerd)) to simulate production behavior and resource bindings locally. Wrangler also offers the option to [develop against remote resources](/workers/local-development/wrangler/#develop-using-remote-resources-and-bindings) with `wrangler dev --remote`, allowing you to test directly with data stored on Cloudflare's network. - -- The **Cloudflare Vite plugin** (`@cloudflare/vite-plugin`), which integrates directly with [Vite](https://vite.dev/) and runs your code in the [Workers Runtime](/workers/reference/how-workers-works/) ([`workerd`](https://github.com/cloudflare/workerd)) to simulate production behavior and resource bindings locally. The Vite plugin also offers features like [hot module replacement (HMR)](https://vite.dev/guide/features.html#hot-module-replacement) and access to Vite's ecosystem and build time transformations. It is currently in **open beta**. +Both Wrangler and the Vite plugin use [Miniflare](/workers/testing/miniflare/) to provide an accurate **local** simulation of the Cloudflare Workers runtime, ([`workerd`](https://github.com/cloudflare/workerd)). If you need to develop with **remote resources**, Wrangler is the only option that provides remote development with the `wrangler dev --remote` command. ## Choosing Between Wrangler and Vite @@ -22,13 +21,13 @@ Deciding between Wrangler and the Cloudflare Vite plugin depends on your project ### When to use Wrangler - **Backend & Workers-focused:** - If you're primarily building APIs, serverless functions, or background tasks that need to closely match production behavior, use Wrangler. + If you're primarily building APIs, serverless functions, or background tasks, use Wrangler. - **Remote development:** - If your project needs the ability to develop and test using production resources and data, use Wrangler's `--remote` flag. + If your project needs the ability to develop and test using production resources and data on Cloudflare's network, use Wrangler's `--remote` flag. - **Simple frontends:** - If you have minimal frontend requirements and don’t need hot reloading or advanced bundling, Wrangler by itself is sufficient. + If you have minimal frontend requirements and don’t need hot reloading or advanced bundling, Wrangler can meet your needs. ### When to use the Cloudflare Vite Plugin @@ -36,7 +35,7 @@ Deciding between Wrangler and the Cloudflare Vite plugin depends on your project If you rely on modern frameworks like React, Vue, Svelte, or Solid, the Vite plugin simplifies setup and integration. - **Rapid iteration (HMR):** - If you need near-instant updates in the browser, the Vite plugin provides Hot Module Replacement (HMR) during local development. + If you need near-instant updates in the browser, the Vite plugin provides [Hot Module Replacement (HMR)](https://vite.dev/guide/features.html#hot-module-replacement) during local development. - **Advanced optimizations:** If you require more advanced optimizations (code splitting, efficient bundling, CSS handling, etc), Vite is a strong fit. diff --git a/src/content/docs/workers/local-development/working-with-data.mdx b/src/content/docs/workers/local-development/working-with-data.mdx new file mode 100644 index 000000000000000..6792aff53bf6339 --- /dev/null +++ b/src/content/docs/workers/local-development/working-with-data.mdx @@ -0,0 +1,131 @@ +--- +pcx_content_type: navigation +title: Working with data +sidebar: + order: 6 +head: [] +description: Working with data during local and remote development +--- + +import { Details, LinkCard, Render, PackageManagers } from "~/components"; + +## Working with data locally + +Whether you are using Wrangler or the [Cloudflare Vite plugin](https://developers.cloudflare.com/workers/vite-plugin/), your workflow for accessing data during locally development remains the same. + +### How it works + +When you run either `wrangler dev` or [`vite`](https://vite.dev/guide/cli#dev-server), [Miniflare](/workers/testing/miniflare/) automatically creates **local versions** of your resources (like [KV](/kv), [D1](/d1/), or [R2](/r2)). This means you **don’t** need to manually set up separate local instances for each service. However, newly created local resources **won’t** contain any data — you'll need to use Wrangler commands with the `--local` flag to populate them. Changes made to local resources won’t affect production data. + +By default, local data resides in the `.wrangler/state` folder, with subdirectories for each resource type. You can delete this folder at any time to reset your local environment, and Miniflare will recreate it the next time you run your `dev` command. + + + +### Changing the local data directory + +If you prefer to specify a different directory for local storage, use the [`--persist-to`](/workers/wrangler/commands/#dev) flag with `wrangler dev`: + + + +:::note +The local persistence folder (like `.wrangler/state` or any custom folder you set) should be added to your `.gitignore` to avoid committing local development data to version control. + +::: + +### Using the `--local` flag + +The following [Wrangler commands](/workers/wrangler/commands/) have a `--local` flag which allows you to create, update, and delete local data during development: + +| Command | +| ---------------------------------------------------- | +| [`d1 execute`](/workers/wrangler/commands/#execute) | +| [`kv key`](/workers/wrangler/commands/#kv-key) | +| [`kv bulk`](/workers/wrangler/commands/#kv-bulk) | +| [`r2 object`](/workers/wrangler/commands/#r2-object) | + +
+If you run `wrangler dev --persist-to ` to specify a custom location for local data, you must also include the same `--persist-to ` when running other Wrangler commands that modify local data (and be sure to include the `--local` flag). + +For example, to create a KV key named `test` with a value of `12345` in a local KV namespace, run: + + + +This command: + +- Sets the KV key `test` to `12345` in the binding `MY_KV_NAMESPACE` (defined in your [Wrangler configuration file](/workers/wrangler/configuration/)). +- Uses `--persist-to worker-local` to ensure the data is created in the **worker-local** directory instead of the default `.wrangler/state`. +- Adds the `--local` flag, indicating you want to modify local data. + +If `--persist-to` is not specified, Wrangler defaults to using `.wrangler/state` for local data. + +
+ +### Clear Wrangler's local storage + +To reset or remove local storage: + +- Delete the entire `.wrangler/state` folder, or +- Delete specific sub-folders within `.wrangler/state` for more targeted clean-up. + +Any folders you remove will be automatically re-created the next time you run `wrangler dev`. + +### Local-only secrets and environment variables + +The [`.dev.vars` file](/workers/configuration/secrets/#local-development-with-secrets) is primarily intended for defining **local secrets** that you do not want to commit to source control. Any environment variables declared in `.dev.vars` will override matching variables in your [Wrangler configuration file](/workers/wrangler/configuration/) **when running `wrangler dev`**. + +For example, if you want to test local credentials or mock a production API endpoint: + +```shell +API_HOST="localhost:4000" +API_ACCOUNT_ID="local_example_user" +``` + +:::note +Since `.dev.vars` is loaded only when running `wrangler dev`, these values do not affect your production environment. Make sure to add `.dev.vars` to your `.gitignore` so you don’t accidentally commit sensitive credentials to version control. +::: + +To learn about setting up environment variables for other non-local environments (such as staging or production), look into [Wrangler Environments](/workers/wrangler/environments/#staging-and-production-environments). + +## Working with remote data + +Sometimes you need to test your Worker against real Cloudflare resources (for example, to ensure accurate data or environment parity). In this case, use the `wrangler dev --remote` command: + + + +### Preview vs. Production Resources + +For certain services, like KV and R2, **remote** development (`wrangler dev --remote`) requires specifying **preview** IDs or names in your [Wrangler configuration file](/workers/wrangler/configuration/). For example: + +- KV uses `preview_id` +- R2 uses `preview_bucket` + +By default, these **preview** resources can be different from your production resources, letting you develop safely without modifying live data. If you do need to work with production data while using `wrangler dev --remote`, simply set the preview ID or name to match your production resource’s ID or name. + + + +## Customize `wrangler dev` + +You can further customize the behavior of `wrangler dev` (for instance, by changing ports or skipping Wrangler's build steps). Refer to [the `wrangler dev` documentation](/workers/wrangler/commands/#dev) for available configuration options. + +:::caution + +There is a bug associated with how outgoing requests are handled when using `wrangler dev --remote`. For more information, read the [Known issues section](/workers/platform/known-issues/#wrangler-dev). + +::: + +## Related resources + +- [D1 local development](/d1/best-practices/local-development/) - The official D1 guide to local development and testing. +- [DevTools](/workers/observability/dev-tools) - Guides to using DevTools to debug your Worker locally. diff --git a/src/content/docs/workers/local-development/wrangler.mdx b/src/content/docs/workers/local-development/wrangler.mdx index 6d8e6e4805d59cc..b6b7e6a79cf061c 100644 --- a/src/content/docs/workers/local-development/wrangler.mdx +++ b/src/content/docs/workers/local-development/wrangler.mdx @@ -30,120 +30,3 @@ To start a local development server for your Worker, navigate to your Worker’s This command runs your Worker code locally, allowing you to test changes in real time. By default, it will store local data in a `.wrangler/state` folder in your project directory. --- - -## Working with local data - -When you run `wrangler dev`, Wrangler automatically creates local versions of your resources (like KV, D1, or R2). This means you **don’t** need to manually set up separate local instances for each service. However, newly created local resources **won’t** contain any data — you'll need to use Wrangler commands with the `--local` flag to populate them. Changes made to local resources won’t affect production data. - -By default, local data resides in the `.wrangler/state` folder. You can delete this folder at any time to reset your local environment, and Wrangler will recreate it the next time you run `wrangler dev`. - - - -### Changing the local data directory - -If you prefer to specify a different directory for local storage, use the [`--persist-to`](/workers/wrangler/commands/#dev) flag with `wrangler dev`: - - - -:::note -The local persistence folder (like `.wrangler/state` or any custom folder you set) should be added to your `.gitignore` to avoid committing local development data to version control. - -::: - -### Using the `--local` flag - -The following [Wrangler commands](/workers/wrangler/commands/) have a `--local` flag which allows you to create, update, and delete local data during development: - -| Command | -| ---------------------------------------------------- | -| [`d1 execute`](/workers/wrangler/commands/#execute) | -| [`kv key`](/workers/wrangler/commands/#kv-key) | -| [`kv bulk`](/workers/wrangler/commands/#kv-bulk) | -| [`r2 object`](/workers/wrangler/commands/#r2-object) | - -
-If you run `wrangler dev --persist-to ` to specify a custom location for local data, you must also include the same `--persist-to ` when running other Wrangler commands that modify local data (and be sure to include the `--local` flag). - -For example, to create a KV key named `test` with a value of `12345` in a local KV namespace, run: - - - -This command: - -- Sets the KV key `test` to `12345` in the binding `MY_KV_NAMESPACE` (defined in your [Wrangler configuration file](/workers/wrangler/configuration/)). -- Uses `--persist-to worker-local` to ensure the data is created in the **worker-local** directory instead of the default `.wrangler/state`. -- Adds the `--local` flag, indicating you want to modify local data. - -If `--persist-to` is not specified, Wrangler defaults to using `.wrangler/state` for local data. - -
- -### Clear Wrangler's local storage - -To reset or remove local storage: - -- Delete the entire `.wrangler/state` folder, or -- Delete specific sub-folders within `.wrangler/state` for more targeted clean-up. - -Any folders you remove will be automatically re-created the next time you run `wrangler dev`. - -### Local-only secrets and environment variables - -The [`.dev.vars` file](/workers/configuration/secrets/#local-development-with-secrets) is primarily intended for defining **local secrets** that you do not want to commit to source control. Any environment variables declared in `.dev.vars` will override matching variables in your [Wrangler configuration file](/workers/wrangler/configuration/) **when running `wrangler dev`**. - -For example, if you want to test local credentials or mock a production API endpoint: - -```shell -API_HOST="localhost:4000" -API_ACCOUNT_ID="local_example_user" -``` - -:::note -Since `.dev.vars` is loaded only when running `wrangler dev`, these values do not affect your production environment. Make sure to add `.dev.vars` to your `.gitignore` so you don’t accidentally commit sensitive credentials to version control. -::: - -To learn about setting up environment variables for other non-local environments (such as staging or production), look into [Wrangler Environments](/workers/wrangler/environments/#staging-and-production-environments). - -## Working with remote data - -Sometimes you need to test your Worker against real Cloudflare resources (for example, to ensure accurate data or environment parity). In this case, use the `wrangler dev --remote` command: - - - -### Preview vs. Production Resources - -For certain services, like KV and R2, **remote** development (`wrangler dev --remote`) requires specifying **preview** IDs or names in your [Wrangler configuration file](/workers/wrangler/configuration/). For example: - -- KV uses `preview_id` -- R2 uses `preview_bucket` - -By default, these **preview** resources can be different from your production resources, letting you develop safely without modifying live data. If you do need to work with production data while using `wrangler dev --remote`, simply set the preview ID or name to match your production resource’s ID or name. - - - -## Customize `wrangler dev` - -You can further customize the behavior of `wrangler dev` (for instance, by changing ports or skipping Wrangler's build steps). Refer to [the `wrangler dev` documentation](/workers/wrangler/commands/#dev) for available configuration options. - -:::caution - -There is a bug associated with how outgoing requests are handled when using `wrangler dev --remote`. For more information, read the [Known issues section](/workers/platform/known-issues/#wrangler-dev). - -::: - -## Related resources - -- [D1 local development](/d1/best-practices/local-development/) - The official D1 guide to local development and testing. -- [DevTools](/workers/observability/dev-tools) - Guides to using DevTools to debug your Worker locally. From 725561333c86faa4d8bf1d75c1373f5e7d41baa6 Mon Sep 17 00:00:00 2001 From: korinne Date: Fri, 4 Apr 2025 17:30:28 -0700 Subject: [PATCH 23/34] updates local development docs --- .../local-development/bindings-per-env.mdx | 12 + .../environment-variables.mdx | 80 +++++ .../docs/workers/local-development/index.mdx | 73 ++++- .../workers/local-development/local-data.mdx | 166 ++++++++++ .../workers/local-development/remote-data.mdx | 53 +++ .../docs/workers/local-development/vite.mdx | 310 ------------------ .../local-development/working-with-data.mdx | 131 -------- .../local-development/wrangler-vs-vite.mdx | 38 +++ .../workers/local-development/wrangler.mdx | 32 -- .../partials/workers/bindings_per_env.mdx | 6 +- 10 files changed, 406 insertions(+), 495 deletions(-) create mode 100644 src/content/docs/workers/local-development/bindings-per-env.mdx create mode 100644 src/content/docs/workers/local-development/environment-variables.mdx create mode 100644 src/content/docs/workers/local-development/local-data.mdx create mode 100644 src/content/docs/workers/local-development/remote-data.mdx delete mode 100644 src/content/docs/workers/local-development/vite.mdx delete mode 100644 src/content/docs/workers/local-development/working-with-data.mdx create mode 100644 src/content/docs/workers/local-development/wrangler-vs-vite.mdx delete mode 100644 src/content/docs/workers/local-development/wrangler.mdx diff --git a/src/content/docs/workers/local-development/bindings-per-env.mdx b/src/content/docs/workers/local-development/bindings-per-env.mdx new file mode 100644 index 000000000000000..62a4c347df5add7 --- /dev/null +++ b/src/content/docs/workers/local-development/bindings-per-env.mdx @@ -0,0 +1,12 @@ +--- +pcx_content_type: navigation +title: Supported bindings in local and remote dev +sidebar: + order: 4 +head: [] +description: Supported bindings in local and remote development +--- + +import { Render } from "~/components"; + + diff --git a/src/content/docs/workers/local-development/environment-variables.mdx b/src/content/docs/workers/local-development/environment-variables.mdx new file mode 100644 index 000000000000000..5fcedb071130e6e --- /dev/null +++ b/src/content/docs/workers/local-development/environment-variables.mdx @@ -0,0 +1,80 @@ +--- +pcx_content_type: navigation +title: Environment variables and secrets +sidebar: + order: 1 +head: [] +description: Configuring environment variables and secrets for local development +--- + +import { Aside, PackageManagers, Steps } from "~/components"; + +During local development, you may need to configure **environment variables** (such as API URLs, feature flags) and **secrets** (API tokens, private keys). You can use a `.dev.vars` file in the root of your project to override environment variables for local development, and both [Wrangler](/workers/configuration/environment-variables/#compare-secrets-and-environment-variables) and the [Vite plugin](/workers/vite-plugin/reference/secrets/) will respect this override. + + + +### Why use a `.dev.vars` file? + +While [`.dev.vars` is commonly used for storing secrets](/workers/configuration/environment-variables/#compare-secrets-and-environment-variables), the file is really just a local override for **any** environment variable — secret or otherwise. This allows you to avoid polluting environment variables in your Wrangler configuration, and provide a way to set local-only values. + +You can also define [environment variables as `[vars]`](/workers/wrangler/environments/#_top) in your Wrangler configuration (for `development`, `staging`, `production`, etc). This is a good way to manage environment-based configuration that you **want checked into your repository** (for example, non-sensitive or shared environment defaults). Using a `.dev.vars` file is specifically for local-only secrets or configuration that you do not want in version control and only want to inject in local dev sessions. + +## Basic setup + + + +1. Create a `.dev.vars` file in your project root. + +2. Add key-value pairs: + + ```ini title=".dev.vars" + API_HOST="localhost:3000" + DEBUG="true" + SECRET_TOKEN="my-local-secret-token" + ``` + +3. Run your `dev` command + + **Wrangler** + + + + **Vite plugin** + + + + +## Multiple local environments with `.dev.vars` + +To simulate different local environments, you can: + + + +1. Create a file named `.dev.vars.` . For example, we'll use `.dev.vars.staging`. + +2. Add key-value pairs: + ```ini title=".dev.vars.staging" + API_HOST="staging.localhost:3000" + DEBUG="false" + SECRET_TOKEN="staging-token" + ``` +3. Run your `dev` command with an `--env` flag: + + **Wrangler** + + + + **Vite plugin** + + + + Only the values from `.dev.vars.staging` will be applied instead of `.dev.vars`. + + + +## Learn more + +- To learn how to configure multiple environments in Wrangler configuration, [read the documenation](/workers/wrangler/environments/#_top). +- To learn how to use Wrangler environments and Vite environments together, [read the Vite plugin documentation](/workers/vite-plugin/reference/cloudflare-environments/) diff --git a/src/content/docs/workers/local-development/index.mdx b/src/content/docs/workers/local-development/index.mdx index 44a8392bcaa4284..fcb262e46e4bead 100644 --- a/src/content/docs/workers/local-development/index.mdx +++ b/src/content/docs/workers/local-development/index.mdx @@ -2,40 +2,77 @@ pcx_content_type: navigation title: Local development sidebar: - order: 5 + order: 6 head: [] description: Develop your Workers locally. --- +import { Details, LinkCard, Render, PackageManagers } from "~/components"; + When building projects on Cloudflare Workers, you have two options for local development: - [**Wrangler**](/workers/wrangler/), using the built-in [`wrangler dev`](/workers/wrangler/commands/#dev) command. - [Vite](https://vite.dev/), using the [**Cloudflare Vite plugin**](/workers/vite-plugin/). -Both Wrangler and the Vite plugin use [Miniflare](/workers/testing/miniflare/) to provide an accurate **local** simulation of the Cloudflare Workers runtime, ([`workerd`](https://github.com/cloudflare/workerd)). If you need to develop with **remote resources**, Wrangler is the only option that provides remote development with the `wrangler dev --remote` command. +Both Wrangler and the Vite plugin use [Miniflare](/workers/testing/miniflare/) to provide an accurate **local** simulation of the Cloudflare Workers runtime, ([`workerd`](https://github.com/cloudflare/workerd)). If you need to [develop with **remote resources**](/workers/local-development/remote-data/), Wrangler is the only option that provides remote development with the `wrangler dev --remote` command. + + + +## Install and start your development server + +### Wrangler + +#### Installation + +To install [Wrangler](https://github.com/cloudflare/workers-sdk/tree/main/packages/wrangler), ensure you have [Node.js](https://nodejs.org/en/) and [npm](https://docs.npmjs.com/getting-started) installed, preferably using a Node version manager like [Volta](https://volta.sh/) or [nvm](https://github.com/nvm-sh/nvm). + + + +#### Start a development server + +To start a development server using Wrangler, run the following: + + + + + +### Vite Plugin -## Choosing Between Wrangler and Vite +#### Installation -Deciding between Wrangler and the Cloudflare Vite plugin depends on your project's focus and development workflow. Here are some quick guidelines to help you choose: +To install the Cloudflare Vite plugin, first start with a simple `package.json` -### When to use Wrangler +```json title="package.json" +{ + "name": "cloudflare-vite-get-started", + "private": true, + "version": "0.0.0", + "type": "module", + "scripts": { + "dev": "vite dev", + "build": "vite build", + "preview": "npm run build && vite preview", + "deploy": "npm run build && wrangler deploy" + } +} +``` -- **Backend & Workers-focused:** - If you're primarily building APIs, serverless functions, or background tasks, use Wrangler. +Then, install the necessary development depenencies: -- **Remote development:** - If your project needs the ability to develop and test using production resources and data on Cloudflare's network, use Wrangler's `--remote` flag. + -- **Simple frontends:** - If you have minimal frontend requirements and don’t need hot reloading or advanced bundling, Wrangler can meet your needs. +This command will install `vite`, along with `@cloudflare/vite-plugin` and `wrangler` as `devDependencies` in your `package.json`. -### When to use the Cloudflare Vite Plugin +#### Start a development server -- **Frontend-centric development:** - If you rely on modern frameworks like React, Vue, Svelte, or Solid, the Vite plugin simplifies setup and integration. +You can then start a development server by running: -- **Rapid iteration (HMR):** - If you need near-instant updates in the browser, the Vite plugin provides [Hot Module Replacement (HMR)](https://vite.dev/guide/features.html#hot-module-replacement) during local development. + -- **Advanced optimizations:** - If you require more advanced optimizations (code splitting, efficient bundling, CSS handling, etc), Vite is a strong fit. + diff --git a/src/content/docs/workers/local-development/local-data.mdx b/src/content/docs/workers/local-development/local-data.mdx new file mode 100644 index 000000000000000..01aea5a749089e9 --- /dev/null +++ b/src/content/docs/workers/local-development/local-data.mdx @@ -0,0 +1,166 @@ +--- +pcx_content_type: navigation +title: Local data +sidebar: + order: 2 +head: [] +description: Working with data during local development +--- + +import { + Details, + LinkCard, + Render, + PackageManagers, + FileTree, + Aside, +} from "~/components"; + +Whether you are using Wrangler or the [Cloudflare Vite plugin](https://developers.cloudflare.com/workers/vite-plugin/), your workflow for **accessing** data during local development remains the same. However, you can only [populate local resources with data](/workers/local-development/local-data/#populating-local-resources-with-data) via the Wrangler CLI. + +### How it works + +When you run either `wrangler dev` or [`vite`](https://vite.dev/guide/cli#dev-server), [Miniflare](/workers/testing/miniflare/) automatically creates **local versions** of your resources (like [KV](/kv), [D1](/d1/), or [R2](/r2)). This means you **don’t** need to manually set up separate local instances for each service. However, newly created local resources **won’t** contain any data — you'll need to use Wrangler commands with the `--local` flag to populate them. Changes made to local resources won’t affect production data. + +## Populating local resources with data + +When you first start developing, your local resources will be empty. You'll need to populate them with data for testing, using the Wrangler CLI. The Vite plugin doesn't provide any special functionality for populating data - it relies entirely on Wrangler CLI commands with the `--local` flag. + +### KV namespaces + + + +#### [Add a single key-value pair](/workers/wrangler/commands/#kv-key) + + + +#### [Buld upload](/workers/wrangler/commands/#kv-bulk) + + + +### R2 buckets + +#### [Upload a file](/workers/wrangler/commands/#r2-object) + + + +You may also include [other metadata](/workers/wrangler/commands/#r2-object-put). + +### D1 databases + +#### [Execute a SQL statement](/wrangler/commands/#d1-execute) + + + +#### [Execute a SQL file](/wrangler/commands/#d1-execute) + + + +### Durable Objects + +For Durable Objects, unlike KV, D1, and R2, there are no CLI commands to populate them with test data. To add data to Durable Objects during local development, you must write application code that creates Durable Object instances and [calls methods on them that store state](/durable-objects/best-practices/access-durable-objects-storage/). This typically involves creating development endpoints or test routes that initialize your Durable Objects with the desired data. + +## Where local data gets stored + +By default, both Wrangler and the Vite plugin store local binding data in the same location: the `.wrangler/state` folder in your project directory. This folder stores data in subdirectories for all local bindings: KV namespaces, R2 buckets, D1 databases, Durable Objects, etc. + +### Clearing local storage + +You can delete the `.wrangler/state` folder at any time to reset your local environment, and Miniflare will recreate it the next time you run your `dev` command. You can also delete specific sub-folders within `.wrangler/state` for more targeted clean-up. + +### Changing the local data directory + +If you prefer to specify a different directory for local storage, you can do so through the Wranlger CLI or in the Vite plugin's configuration. + +#### Using Wrangler + +Use the [`--persist-to`](/workers/wrangler/commands/#dev) flag with `wrangler dev`. You need to specify this flag every time you run the `dev` command: + + + +:::note +The local persistence folder (like `.wrangler/state` or any custom folder you set) should be added to your `.gitignore` to avoid committing local development data to version control. +::: + +
+If you run `wrangler dev --persist-to ` to specify a custom location for local data, you must also include the same `--persist-to ` when running other Wrangler commands that modify local data (and be sure to include the `--local` flag). + +For example, to create a KV key named `test` with a value of `12345` in a local KV namespace, run: + + + +This command: + +- Sets the KV key `test` to `12345` in the binding `MY_KV_NAMESPACE` (defined in your [Wrangler configuration file](/workers/wrangler/configuration/)). +- Uses `--persist-to worker-local` to ensure the data is created in the **worker-local** directory instead of the default `.wrangler/state`. +- Adds the `--local` flag, indicating you want to modify local data. + +If `--persist-to` is not specified, Wrangler defaults to using `.wrangler/state` for local data. + +
+ +#### Using the Cloudflare Vite plugin + +To customize where the Vite plugin stores local data, configure the [`persistState` option](/workers/vite-plugin/reference/api/#interface-pluginconfig) in your Vite config file: + +```js title="vite.config.js" +import { defineConfig } from "vite"; +import { cloudflare } from "@cloudflare/vite-plugin"; + +export default defineConfig({ + plugins: [ + cloudflare({ + persistState: "./my-custom-directory", + }), + ], +}); +``` + +#### Sharing state between tools + +If you want Wrangler and the Vite plugin to share the same state, configure them to use the same persistence path. + +## Customize `wrangler dev` + +You can further customize the behavior of `wrangler dev` (for instance, by changing ports or skipping Wrangler's build steps). Refer to [the `wrangler dev` documentation](/workers/wrangler/commands/#dev) for available configuration options. + +## Customize the Cloudflare Vite plugin + +You can also [customize the Vite plugin](/workers/vite-plugin/reference/api/), such as changing ports or calling other Workers. + +## Debugging + +- [DevTools](/workers/observability/dev-tools) - Guides to using DevTools to debug your Worker locally. +- [Debugging with the Vite plugin](/workers/vite-plugin/reference/debugging/) diff --git a/src/content/docs/workers/local-development/remote-data.mdx b/src/content/docs/workers/local-development/remote-data.mdx new file mode 100644 index 000000000000000..3db67a224aaa308 --- /dev/null +++ b/src/content/docs/workers/local-development/remote-data.mdx @@ -0,0 +1,53 @@ +--- +pcx_content_type: navigation +title: Remote data +sidebar: + order: 3 +head: [] +description: Working with data during remote development +--- + +import { + Details, + LinkCard, + Render, + PackageManagers, + FileTree, +} from "~/components"; + +When developing Workers applications, you can use Wrangler's remote development mode (via [`wrangler dev --remote`](/workers/wrangler/commands/#dev)) to test your code on Cloudflare's global network before +deploying to production. Remote development is [**not** supported in the Vite plugin](/local-development/wrangler-vs-vite/). + + + +### How It Works + +The `wrangler dev --remote` command creates a temporary preview deployment on Cloudflare's infrastructure, allowing you to test your Worker in an environment that closely mirrors production. + +When you run `wrangler dev --remote`: + +- Your code is uploaded to a temporary preview environment on Cloudflare's infrastructure. +- Changes to your code are automatically uploaded as you save. +- All requests and execution happen on Cloudflare's global network +- The preview automatically terminates when you exit the command + +## When to Use Remote Development + +- You need to develop using [bindings that don't work locally](/local-development/bindings-per-env/) (such as [Browser Rendering](/browser-rendering/)). +- You need to verify behavior specifically on Cloudflare's infrastructure. +- You want to work with preview resources that mirror production. + +## Isolating from Production + +To protect production data, you can specify preview resources in your [Wrangler configuration](/workers/wrangler/configuration/), such as: + +- [Preview namespaces for KV stores](/workers/wrangler/configuration/#kv-namespaces):`preview_id`. + - This option is **required** when using `wrangler dev --remote`. +- [Preview buckets for R2 storage](/workers/wrangler/configuration/#r2-buckets): `preview_bucket_name`. +- [Preview database IDs for D1](/workers/wrangler/configuration/#d1-databases): `preview_database_id` + +This separation ensures your development activities don't impact production data while still providing a realistic testing environment. + +## Limitations + +- When you run a remote development session using the `--remote` flag, a limit of 50 [routes](/workers/configuration/routing/routes/) per zone is enforced. Learn more in[ Workers platform limits](/workers/platform/limits/#number-of-routes-per-zone-when-using-wrangler-dev---remote). diff --git a/src/content/docs/workers/local-development/vite.mdx b/src/content/docs/workers/local-development/vite.mdx deleted file mode 100644 index 52fbd37fe901684..000000000000000 --- a/src/content/docs/workers/local-development/vite.mdx +++ /dev/null @@ -1,310 +0,0 @@ ---- -title: Vite -pcx_content_type: concept -sidebar: - order: 7 - group: - badge: Beta -head: [] -description: Locally develop and test changes with the Cloudflare Vite plugin ---- - -import { - Badge, - InlineBadge, - PackageManagers, - WranglerConfig, -} from "~/components"; - -## Local development with Vite - -The Cloudflare Vite plugin (`@cloudflare/vite-plugin`) integrates your Worker code directly with [Vite](https://vite.dev/). Like `wrangler dev`, this approach uses `workerd` under the hood as well, and provides: - -- Direct access to Workers [runtime APIs](/workers/runtime-apis/) and [bindings](/workers/runtime-apis/bindings/) -- [Hot module replacement (HMR)](https://vite.dev/guide/features.html#hot-module-replacement) for near-instant feedback on code changes. -- A single workflow (`vite dev`, `vite build`, `vite preview`) that handles both your client-side and Worker code. -- An “input” Wrangler config file and an automatically generated “output” config file (used for preview and deployment). - -If you are building anything that involves a front-end using [Workers static assets](/workers/static-assets/), the Vite approach can be particularly powerful. - -## Get started - -#### 1. Create your project directory and add a minimal package.JSON: - -```json -{ - "name": "cloudflare-vite-quick-start", - "private": true, - "version": "0.0.0", - "type": "module", - "scripts": { - "dev": "vite", - "build": "vite build", - "preview": "vite preview" - } -} -``` - -:::note -Ensure that you include `"type": "module"` in order to use ES modules by default. -::: - -#### 2. Install dependencies - - - -#### 3. Create a Vite config file (`vite.config.ts`) and include the Cloudflare plugin: - -```ts -// vite.config.ts - -import { defineConfig } from "vite"; -import { cloudflare } from "@cloudflare/vite-plugin"; - -export default defineConfig({ - plugins: [cloudflare()], -}); -``` - -#### 4. Create a Worker configuration file (`wrangler.toml` or `wrangler.jsonc`): - - - -```toml -name = "cloudflare-vite-quick-start" -compatibility_date = "2024-12-30" -main = "./src/index.ts" -``` - - - -#### 5. Create a Worker entry file (`src/index.ts`): - -```ts -// src/index.ts - -export default { - fetch() { - return new Response(`Running in ${navigator.userAgent}!`); - }, -}; -``` - -#### 6. Run local development - -```sh -npm run dev -``` - -This starts a local development server, using the Workers runtime behind the scenes. When you are ready, you can build (`npm run build)`, preview (`npm run preview`), and deploy (`npm exec wrangler deploy`) your application. - -## Cloudflare environments - -You can specify multiple [Cloudflare environments](/workers/wrangler/environments/) in your Worker confiuration (for example, `[env.staging]` or `[env.production]`). With the Cloudflare Vite plugin, you can select an environment at `dev` or `build` time by providing the `CLOUDFLARE_ENV` environment variable. - -For example, let's say you have the following Wrangler configuration file: - - - -```toml -name = "my-worker" -compatibility_date = "2024-12-30" -main = "./src/index.ts" - -vars = { MY_VAR = "Top-level var" } - -[env.staging] -vars = { MY_VAR = "Staging var" } - -[env.production] -vars = { MY_VAR = "Production var" } -``` - - - -With the Vite plugin, you can run: - -```sh -CLOUDFLARE_ENV=production vite build -``` - -The output `wrangler.json` file generated by the build will be a flattened configuration for the `'production'` Cloudflare environment. This combines [top-level only](/workers/wrangler/configuration/#top-level-only-keys), [inheritable](/workers/wrangler/configuration/#inheritable-keys), and [non-inheritable](/workers/wrangler/configuration/#non-inheritable-keys) keys. - -In this case, - -- The value of `MY_VAR` will be `'Production var'`. -- The name of the Worker will be `'my-worker-production'`. - -This is because the environment name is automatically appended to the top-level Worker name. - -:::note -The default Vite environment name for a Worker is always the top-level Worker name. -This enables you to reference the Worker consistently in your Vite config when using multiple Cloudflare environments. -::: - -### Cloudflare Environments during development - -You can also specify Cloudflare environments in development. For example, you could run: - -```sh -CLOUDFLARE_ENV=development vite dev -``` - -It is common to use the default top-level environment as the development environment and then add additional environments as necessary. - -:::note -Running `vite dev` or `vite build` without providing `CLOUDFLARE_ENV` will use the default top-level Cloudflare environment. -In the above example, the value of `MY_VAR` would be `'Top-level var'`. -Since Cloudflare environments are applied at `dev` and `build` time, specifying `CLOUDFLARE_ENV` when running `vite preview` or `wrangler deploy` will have no effect. -::: - -### Combining Cloudflare Environments and Vite Modes - -You may want to combine the concepts of [Cloudflare environments](/workers/wrangler/environments/) and [Vite modes](https://vite.dev/guide/env-and-mode.html#modes). - -With this approach, the Vite mode can be used to select the Cloudflare environment and a single method can be used to determine environment specific configuration and code. - -Let's use the previous example: - - - -```toml -# wrangler.toml - -name = "my-worker" -compatibility_date = "2024-12-30" -main = "./src/index.ts" - -vars = { MY_VAR = "Top-level var" } - -[env.staging] -vars = { MY_VAR = "Staging var" } - -[env.production] -vars = { MY_VAR = "Production var" } -``` - - - -Next, provide `.env.staging` and `.env.production` files: - -```sh -# .env.staging - -CLOUDFLARE_ENV=staging -``` - -```sh -# .env.production - -CLOUDFLARE_ENV=production -``` - -By default, `vite build` uses the **'production'** Vite mode, which loads `.env.production` to get the environment variables that are used in the build. - -- This sets `CLOUDFLARE_ENV=production`, selecting the production Cloudflare environment. -- `MY_VAR` becomes `'Production var'`. - -To build with the **staging mode**, run: - -```sh -vite build --mode staging -``` - -- This loads `.env.staging`. -- The value of `MY_VAR` will be `'Staging var'`. - -## Secrets in local development - -Secrets can be provided to your Worker in local development using a [`.dev.vars`](/workers/configuration/secrets/#local-development-with-secrets) file. If you are using [Cloudflare Environments](#cloudflare-environments) then the relevant `.dev.vars` file will be selected. - -For example, - -```sh -CLOUDFLARE_ENV=staging vite dev -``` - -Will load `.dev.vars.staging` if it exists and otherwise fall back to `.dev.vars`. - -:::note -When you run `vite build`, the relevant `.dev.vars[.env-name]` file is copied to the output directory for use during `vite preview`. It is **not** deployed with your Worker. -::: - -## Migrating from `wrangler dev` - -Migrating from `wrangler dev` is a simple process and you can follow the instructions in [Get started](#get-started). - -There are a few key differences to highlight: - -#### 1. Input and output Worker configuration files - -- Your existing Wrangler configuration file is treated as an **input** configuration. -- A separate output configuration is generated at build time, capturing a snapshot of your config and referencing your build artifacts. This is the configuration that is used for **preview** and **deployment**. - -#### 2. Redundant fields in the Wrangler configuration file - -- Some fields are either ignored or replaced by Vite options, as they are either no longer applicable or are replaced by Vite equivalents. -- If these options are provided, then warnings will be printed to the console with suggestions for how to proceed. For example, you will see console warnings if you use fields like `alias` or `define` that have direct Vite equivalents. - -## API - -### `cloudflare` - -The `cloudflare` plugin should be included in the Vite `plugins` array: - -```ts {4, 7} -// vite.config.ts - -import { defineConfig } from "vite"; -import { cloudflare } from "@cloudflare/vite-plugin"; - -export default defineConfig({ - plugins: [cloudflare()], -}); -``` - -It accepts an optional `PluginConfig` parameter. - -### `interface PluginConfig` - -- `configPath?: string` - - An optional path to your Worker config file. - By default, a `wrangler.toml`, `wrangler.json`, or `wrangler.jsonc` file in the root of your application will be used as the Worker config. - -- `viteEnvironment?: { name?: string }` - - Optional Vite environment options. - By default, the environment name is the Worker name with `-` characters replaced with `_`. - Setting the name here will override this. - -- `persistState?: boolean | { path: string }` - - An optional override for state persistence. - By default, state is persisted to `.wrangler/state` in a `v3` subdirectory. - A custom `path` can be provided or, alternatively, persistence can be disabled by setting the value to `false`. - -- `auxiliaryWorkers?: Array` - - An optional array of auxiliary Workers. - You can use [service bindings](/workers/runtime-apis/bindings/service-bindings/) to call auxiliary Workers from your main (entry) Worker. - All requests are routed through your entry Worker. - During the build, each Worker is output to a separate subdirectory of `dist`. - -:::note -When running `wrangler deploy`, only your main (entry) Worker will be deployed. -If using multiple Workers, each must be deployed individually. -You can inspect the `dist` directory and then run `wrangler deploy -c path-to-worker-output-config` for each. -::: - -### `interface AuxiliaryWorkerConfig` - -- `configPath: string` - - A required path to your Worker config file. - -- `viteEnvironment?: { name?: string }` - - Optional Vite environment options. - By default, the environment name is the Worker name with `-` characters replaced with `_`. - Setting the name here will override this. diff --git a/src/content/docs/workers/local-development/working-with-data.mdx b/src/content/docs/workers/local-development/working-with-data.mdx deleted file mode 100644 index 6792aff53bf6339..000000000000000 --- a/src/content/docs/workers/local-development/working-with-data.mdx +++ /dev/null @@ -1,131 +0,0 @@ ---- -pcx_content_type: navigation -title: Working with data -sidebar: - order: 6 -head: [] -description: Working with data during local and remote development ---- - -import { Details, LinkCard, Render, PackageManagers } from "~/components"; - -## Working with data locally - -Whether you are using Wrangler or the [Cloudflare Vite plugin](https://developers.cloudflare.com/workers/vite-plugin/), your workflow for accessing data during locally development remains the same. - -### How it works - -When you run either `wrangler dev` or [`vite`](https://vite.dev/guide/cli#dev-server), [Miniflare](/workers/testing/miniflare/) automatically creates **local versions** of your resources (like [KV](/kv), [D1](/d1/), or [R2](/r2)). This means you **don’t** need to manually set up separate local instances for each service. However, newly created local resources **won’t** contain any data — you'll need to use Wrangler commands with the `--local` flag to populate them. Changes made to local resources won’t affect production data. - -By default, local data resides in the `.wrangler/state` folder, with subdirectories for each resource type. You can delete this folder at any time to reset your local environment, and Miniflare will recreate it the next time you run your `dev` command. - - - -### Changing the local data directory - -If you prefer to specify a different directory for local storage, use the [`--persist-to`](/workers/wrangler/commands/#dev) flag with `wrangler dev`: - - - -:::note -The local persistence folder (like `.wrangler/state` or any custom folder you set) should be added to your `.gitignore` to avoid committing local development data to version control. - -::: - -### Using the `--local` flag - -The following [Wrangler commands](/workers/wrangler/commands/) have a `--local` flag which allows you to create, update, and delete local data during development: - -| Command | -| ---------------------------------------------------- | -| [`d1 execute`](/workers/wrangler/commands/#execute) | -| [`kv key`](/workers/wrangler/commands/#kv-key) | -| [`kv bulk`](/workers/wrangler/commands/#kv-bulk) | -| [`r2 object`](/workers/wrangler/commands/#r2-object) | - -
-If you run `wrangler dev --persist-to ` to specify a custom location for local data, you must also include the same `--persist-to ` when running other Wrangler commands that modify local data (and be sure to include the `--local` flag). - -For example, to create a KV key named `test` with a value of `12345` in a local KV namespace, run: - - - -This command: - -- Sets the KV key `test` to `12345` in the binding `MY_KV_NAMESPACE` (defined in your [Wrangler configuration file](/workers/wrangler/configuration/)). -- Uses `--persist-to worker-local` to ensure the data is created in the **worker-local** directory instead of the default `.wrangler/state`. -- Adds the `--local` flag, indicating you want to modify local data. - -If `--persist-to` is not specified, Wrangler defaults to using `.wrangler/state` for local data. - -
- -### Clear Wrangler's local storage - -To reset or remove local storage: - -- Delete the entire `.wrangler/state` folder, or -- Delete specific sub-folders within `.wrangler/state` for more targeted clean-up. - -Any folders you remove will be automatically re-created the next time you run `wrangler dev`. - -### Local-only secrets and environment variables - -The [`.dev.vars` file](/workers/configuration/secrets/#local-development-with-secrets) is primarily intended for defining **local secrets** that you do not want to commit to source control. Any environment variables declared in `.dev.vars` will override matching variables in your [Wrangler configuration file](/workers/wrangler/configuration/) **when running `wrangler dev`**. - -For example, if you want to test local credentials or mock a production API endpoint: - -```shell -API_HOST="localhost:4000" -API_ACCOUNT_ID="local_example_user" -``` - -:::note -Since `.dev.vars` is loaded only when running `wrangler dev`, these values do not affect your production environment. Make sure to add `.dev.vars` to your `.gitignore` so you don’t accidentally commit sensitive credentials to version control. -::: - -To learn about setting up environment variables for other non-local environments (such as staging or production), look into [Wrangler Environments](/workers/wrangler/environments/#staging-and-production-environments). - -## Working with remote data - -Sometimes you need to test your Worker against real Cloudflare resources (for example, to ensure accurate data or environment parity). In this case, use the `wrangler dev --remote` command: - - - -### Preview vs. Production Resources - -For certain services, like KV and R2, **remote** development (`wrangler dev --remote`) requires specifying **preview** IDs or names in your [Wrangler configuration file](/workers/wrangler/configuration/). For example: - -- KV uses `preview_id` -- R2 uses `preview_bucket` - -By default, these **preview** resources can be different from your production resources, letting you develop safely without modifying live data. If you do need to work with production data while using `wrangler dev --remote`, simply set the preview ID or name to match your production resource’s ID or name. - - - -## Customize `wrangler dev` - -You can further customize the behavior of `wrangler dev` (for instance, by changing ports or skipping Wrangler's build steps). Refer to [the `wrangler dev` documentation](/workers/wrangler/commands/#dev) for available configuration options. - -:::caution - -There is a bug associated with how outgoing requests are handled when using `wrangler dev --remote`. For more information, read the [Known issues section](/workers/platform/known-issues/#wrangler-dev). - -::: - -## Related resources - -- [D1 local development](/d1/best-practices/local-development/) - The official D1 guide to local development and testing. -- [DevTools](/workers/observability/dev-tools) - Guides to using DevTools to debug your Worker locally. diff --git a/src/content/docs/workers/local-development/wrangler-vs-vite.mdx b/src/content/docs/workers/local-development/wrangler-vs-vite.mdx new file mode 100644 index 000000000000000..354e502f27521c7 --- /dev/null +++ b/src/content/docs/workers/local-development/wrangler-vs-vite.mdx @@ -0,0 +1,38 @@ +--- +pcx_content_type: navigation +title: Wrangler vs Vite +sidebar: + order: 5 +head: [] +description: Choosing between using Wrangler or Vite during development. +--- + +Deciding between Wrangler and the Cloudflare Vite plugin depends on your project's focus and development workflow. Here are some quick guidelines to help you choose: + +### When to use Wrangler + +- **Backend & Workers-focused:** + If you're primarily building APIs, serverless functions, or background tasks, use Wrangler. + +- **Remote development:** + If your project needs the ability to develop and test using production resources and data on Cloudflare's network, use Wrangler's `--remote` flag. + +- **Simple frontends:** + If you have minimal frontend requirements and don’t need hot reloading or advanced bundling, Wrangler may be sufficient. + +### When to use the Cloudflare Vite Plugin + +- **Frontend-centric development:** + If you already use Vite with modern frontend frameworks like React, Vue, Svelte, or Solid, the Vite plugin integrates into your development workflow. + +- **React Router v7:** + If you are using [React Router v7](https://reactrouter.com/) (the successor to Remix), it is officially supported by the Vite plugin as a full-stack SSR framework. + +- **Rapid iteration (HMR):** + If you need near-instant updates in the browser, the Vite plugin provides [Hot Module Replacement (HMR)](https://vite.dev/guide/features.html#hot-module-replacement) during local development. + +- **Advanced optimizations:** + If you require more advanced optimizations (code splitting, efficient bundling, CSS handling, build time transformations, etc.), Vite is a strong fit. + +- **Greater flexibility:** + Due to Vite's advanced configuration options and large ecosystem of plugins, there is more flexibility to customize your development experience and build output. diff --git a/src/content/docs/workers/local-development/wrangler.mdx b/src/content/docs/workers/local-development/wrangler.mdx deleted file mode 100644 index b6b7e6a79cf061c..000000000000000 --- a/src/content/docs/workers/local-development/wrangler.mdx +++ /dev/null @@ -1,32 +0,0 @@ ---- -title: Wrangler -pcx_content_type: concept -sidebar: - order: 6 -head: [] -description: Locally develop and test changes with `wrangler dev` ---- - -import { Details, LinkCard, Render, PackageManagers } from "~/components"; - -## Local development with Wrangler - -The [Wrangler CLI](/workers/wrangler/) provides a [`dev`](/workers/wrangler/commands/#dev) command that starts a local development server directly on your machine. It uses a combination of the Workers Runtime (`workerd`) and [Miniflare](https://github.com/cloudflare/workers-sdk/tree/main/packages/miniflare), a simulator that allows you to test your Worker against additional resources like [R2](/r2/), [KV](/kv), [D1](/d1), and [Durable Objects](/durable-objects). - -:::note - -This guide assumes you are using [Wrangler v3.0](https://blog.cloudflare.com/wrangler3/) or later. - -Users new to Wrangler CLI and Cloudflare Workers should visit the [Wrangler Install/Update guide](/workers/wrangler/install-and-update) to install `wrangler`. - -::: - -## Start a local development server - -To start a local development server for your Worker, navigate to your Worker’s project folder and run: - - - -This command runs your Worker code locally, allowing you to test changes in real time. By default, it will store local data in a `.wrangler/state` folder in your project directory. - ---- diff --git a/src/content/partials/workers/bindings_per_env.mdx b/src/content/partials/workers/bindings_per_env.mdx index b6d65308f21e5cf..d2f620835ffb867 100644 --- a/src/content/partials/workers/bindings_per_env.mdx +++ b/src/content/partials/workers/bindings_per_env.mdx @@ -2,11 +2,9 @@ {} --- -## Supported bindings in local and remote dev +**Local Development:** Includes [`wrangler dev`](/workers/wrangler/commands/#dev) (without the `--remote` flag) and the [Cloudflare Vite plugin](/workers/vite-plugin/). This mode simulates the Cloudflare Workers environment locally. -- **Local Development:** Includes [`wrangler dev`](/workers/wrangler/commands/#dev) (without the `--remote` flag) and the [Cloudflare Vite plugin](/workers/local-development/vite/). This mode simulates the Cloudflare Workers environment locally. - -- **Remote Development:** Uses [`wrangler dev --remote`](/workers/wrangler/commands/#dev)), deploying your code to Cloudflare’s infrastructure during development. This ensures all bindings and resources match production conditions. There is no Vite plugin equivalent for testing remote resources. +**Remote Development:** Uses [`wrangler dev --remote`](/workers/wrangler/commands/#dev)), deploying your code to Cloudflare’s infrastructure during development. This ensures all bindings and resources match production conditions. There is **no Vite plugin equivalent** for testing remote resources. | Binding | Local (Wrangler & Vite) | Remote (Wrangler only) | | --------------------------------------- | :---------------------: | :--------------------: | From 9af5af8feb0a9ce28bb37d9fd1a33f9d051a49c5 Mon Sep 17 00:00:00 2001 From: korinne <40270578+korinne@users.noreply.github.com> Date: Mon, 7 Apr 2025 11:02:06 -0700 Subject: [PATCH 24/34] Update src/content/docs/workers/local-development/local-data.mdx Co-authored-by: James Opstad <13586373+jamesopstad@users.noreply.github.com> --- src/content/docs/workers/local-development/local-data.mdx | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/content/docs/workers/local-development/local-data.mdx b/src/content/docs/workers/local-development/local-data.mdx index 01aea5a749089e9..6740b9ac5e2f301 100644 --- a/src/content/docs/workers/local-development/local-data.mdx +++ b/src/content/docs/workers/local-development/local-data.mdx @@ -24,7 +24,7 @@ When you run either `wrangler dev` or [`vite`](https://vite.dev/guide/cli#dev-se ## Populating local resources with data -When you first start developing, your local resources will be empty. You'll need to populate them with data for testing, using the Wrangler CLI. The Vite plugin doesn't provide any special functionality for populating data - it relies entirely on Wrangler CLI commands with the `--local` flag. +When you first start developing, your local resources will be empty. You'll need to populate them with data using the Wrangler CLI. ### KV namespaces From b2766b8da2ca21756a337e76280f55fe89626ac7 Mon Sep 17 00:00:00 2001 From: korinne <40270578+korinne@users.noreply.github.com> Date: Mon, 7 Apr 2025 11:02:25 -0700 Subject: [PATCH 25/34] Update src/content/docs/workers/local-development/local-data.mdx Co-authored-by: James Opstad <13586373+jamesopstad@users.noreply.github.com> --- .../docs/workers/local-development/local-data.mdx | 12 ------------ 1 file changed, 12 deletions(-) diff --git a/src/content/docs/workers/local-development/local-data.mdx b/src/content/docs/workers/local-development/local-data.mdx index 6740b9ac5e2f301..0f816d6cad3ec96 100644 --- a/src/content/docs/workers/local-development/local-data.mdx +++ b/src/content/docs/workers/local-development/local-data.mdx @@ -152,15 +152,3 @@ export default defineConfig({ If you want Wrangler and the Vite plugin to share the same state, configure them to use the same persistence path. -## Customize `wrangler dev` - -You can further customize the behavior of `wrangler dev` (for instance, by changing ports or skipping Wrangler's build steps). Refer to [the `wrangler dev` documentation](/workers/wrangler/commands/#dev) for available configuration options. - -## Customize the Cloudflare Vite plugin - -You can also [customize the Vite plugin](/workers/vite-plugin/reference/api/), such as changing ports or calling other Workers. - -## Debugging - -- [DevTools](/workers/observability/dev-tools) - Guides to using DevTools to debug your Worker locally. -- [Debugging with the Vite plugin](/workers/vite-plugin/reference/debugging/) From 54bbee8ebcbcd10874017458109a5990b03767ed Mon Sep 17 00:00:00 2001 From: korinne <40270578+korinne@users.noreply.github.com> Date: Mon, 7 Apr 2025 11:03:20 -0700 Subject: [PATCH 26/34] Update src/content/docs/workers/local-development/wrangler-vs-vite.mdx Co-authored-by: Kody Jackson --- .../docs/workers/local-development/wrangler-vs-vite.mdx | 3 +++ 1 file changed, 3 insertions(+) diff --git a/src/content/docs/workers/local-development/wrangler-vs-vite.mdx b/src/content/docs/workers/local-development/wrangler-vs-vite.mdx index 354e502f27521c7..ada9534bbeaf4d6 100644 --- a/src/content/docs/workers/local-development/wrangler-vs-vite.mdx +++ b/src/content/docs/workers/local-development/wrangler-vs-vite.mdx @@ -22,6 +22,9 @@ Deciding between Wrangler and the Cloudflare Vite plugin depends on your project ### When to use the Cloudflare Vite Plugin + +Use the [Vite plugin](/workers/vite-plugin/) for: + - **Frontend-centric development:** If you already use Vite with modern frontend frameworks like React, Vue, Svelte, or Solid, the Vite plugin integrates into your development workflow. From 3a6d19a8c89a7124c1622a19a6276848bc6ec1e7 Mon Sep 17 00:00:00 2001 From: korinne <40270578+korinne@users.noreply.github.com> Date: Mon, 7 Apr 2025 11:03:35 -0700 Subject: [PATCH 27/34] Update src/content/docs/workers/local-development/remote-data.mdx Co-authored-by: Kody Jackson --- src/content/docs/workers/local-development/remote-data.mdx | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/content/docs/workers/local-development/remote-data.mdx b/src/content/docs/workers/local-development/remote-data.mdx index 3db67a224aaa308..6b9090d241bf8d9 100644 --- a/src/content/docs/workers/local-development/remote-data.mdx +++ b/src/content/docs/workers/local-development/remote-data.mdx @@ -33,7 +33,7 @@ When you run `wrangler dev --remote`: ## When to Use Remote Development -- You need to develop using [bindings that don't work locally](/local-development/bindings-per-env/) (such as [Browser Rendering](/browser-rendering/)). +- You need to develop using [bindings that don't work locally](/workers/local-development/bindings-per-env/) (such as [Browser Rendering](/browser-rendering/)). - You need to verify behavior specifically on Cloudflare's infrastructure. - You want to work with preview resources that mirror production. From 32273fb980b28ea9e01be1ee7fe6d3dfbf9588fc Mon Sep 17 00:00:00 2001 From: korinne <40270578+korinne@users.noreply.github.com> Date: Mon, 7 Apr 2025 11:03:46 -0700 Subject: [PATCH 28/34] Update src/content/docs/workers/local-development/local-data.mdx Co-authored-by: Kody Jackson --- src/content/docs/workers/local-development/local-data.mdx | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/content/docs/workers/local-development/local-data.mdx b/src/content/docs/workers/local-development/local-data.mdx index 0f816d6cad3ec96..9f712e1bce608e9 100644 --- a/src/content/docs/workers/local-development/local-data.mdx +++ b/src/content/docs/workers/local-development/local-data.mdx @@ -72,7 +72,7 @@ You may also include [other metadata](/workers/wrangler/commands/#r2-object-put) args='d1 execute --command="" --local' /> -#### [Execute a SQL file](/wrangler/commands/#d1-execute) +#### [Execute a SQL file](/workers/wrangler/commands/#d1-execute) Date: Mon, 7 Apr 2025 11:03:59 -0700 Subject: [PATCH 29/34] Update src/content/docs/workers/local-development/local-data.mdx Co-authored-by: Kody Jackson --- src/content/docs/workers/local-development/local-data.mdx | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/content/docs/workers/local-development/local-data.mdx b/src/content/docs/workers/local-development/local-data.mdx index 9f712e1bce608e9..1714d8dfb5c9c13 100644 --- a/src/content/docs/workers/local-development/local-data.mdx +++ b/src/content/docs/workers/local-development/local-data.mdx @@ -64,7 +64,7 @@ You may also include [other metadata](/workers/wrangler/commands/#r2-object-put) ### D1 databases -#### [Execute a SQL statement](/wrangler/commands/#d1-execute) +#### [Execute a SQL statement](/workers/wrangler/commands/#d1-execute) Date: Mon, 7 Apr 2025 11:04:30 -0700 Subject: [PATCH 30/34] Update src/content/docs/workers/local-development/local-data.mdx Co-authored-by: Brendan Irvine-Broque --- src/content/docs/workers/local-development/local-data.mdx | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/content/docs/workers/local-development/local-data.mdx b/src/content/docs/workers/local-development/local-data.mdx index 1714d8dfb5c9c13..163eadc2b625a42 100644 --- a/src/content/docs/workers/local-development/local-data.mdx +++ b/src/content/docs/workers/local-development/local-data.mdx @@ -30,7 +30,7 @@ When you first start developing, your local resources will be empty. You'll need From 9e0b348281bdcb62ce48f21bfbf5952d683d343b Mon Sep 17 00:00:00 2001 From: korinne <40270578+korinne@users.noreply.github.com> Date: Mon, 7 Apr 2025 11:04:55 -0700 Subject: [PATCH 31/34] Update src/content/docs/workers/local-development/index.mdx Co-authored-by: James Opstad <13586373+jamesopstad@users.noreply.github.com> --- src/content/docs/workers/local-development/index.mdx | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/content/docs/workers/local-development/index.mdx b/src/content/docs/workers/local-development/index.mdx index fcb262e46e4bead..1d81dd62f5d63ac 100644 --- a/src/content/docs/workers/local-development/index.mdx +++ b/src/content/docs/workers/local-development/index.mdx @@ -14,7 +14,7 @@ When building projects on Cloudflare Workers, you have two options for local dev - [**Wrangler**](/workers/wrangler/), using the built-in [`wrangler dev`](/workers/wrangler/commands/#dev) command. - [Vite](https://vite.dev/), using the [**Cloudflare Vite plugin**](/workers/vite-plugin/). -Both Wrangler and the Vite plugin use [Miniflare](/workers/testing/miniflare/) to provide an accurate **local** simulation of the Cloudflare Workers runtime, ([`workerd`](https://github.com/cloudflare/workerd)). If you need to [develop with **remote resources**](/workers/local-development/remote-data/), Wrangler is the only option that provides remote development with the `wrangler dev --remote` command. +Both Wrangler and the Vite plugin use [Miniflare](/workers/testing/miniflare/) to provide an accurate **local** simulation of the Cloudflare Workers runtime, ([`workerd`](https://github.com/cloudflare/workerd)). If you need to [develop with **remote resources**](/workers/local-development/remote-data/), Wrangler is the only option, and provides remote development via the `wrangler dev --remote` command. Date: Mon, 7 Apr 2025 11:23:33 -0700 Subject: [PATCH 32/34] adds updates to remove separate vite vs wrangler docs, small changes --- .../environment-variables.mdx | 10 +-- .../docs/workers/local-development/index.mdx | 69 ++++++------------- .../workers/local-development/remote-data.mdx | 2 +- .../local-development/wrangler-vs-vite.mdx | 41 ----------- .../partials/workers/bindings_per_env.mdx | 4 +- 5 files changed, 30 insertions(+), 96 deletions(-) delete mode 100644 src/content/docs/workers/local-development/wrangler-vs-vite.mdx diff --git a/src/content/docs/workers/local-development/environment-variables.mdx b/src/content/docs/workers/local-development/environment-variables.mdx index 5fcedb071130e6e..eca45c3ce77635a 100644 --- a/src/content/docs/workers/local-development/environment-variables.mdx +++ b/src/content/docs/workers/local-development/environment-variables.mdx @@ -17,9 +17,9 @@ During local development, you may need to configure **environment variables** (s ### Why use a `.dev.vars` file? -While [`.dev.vars` is commonly used for storing secrets](/workers/configuration/environment-variables/#compare-secrets-and-environment-variables), the file is really just a local override for **any** environment variable — secret or otherwise. This allows you to avoid polluting environment variables in your Wrangler configuration, and provide a way to set local-only values. +Use `.dev.vars` to set local overrides for environment variables that should not be checked into your repository. -You can also define [environment variables as `[vars]`](/workers/wrangler/environments/#_top) in your Wrangler configuration (for `development`, `staging`, `production`, etc). This is a good way to manage environment-based configuration that you **want checked into your repository** (for example, non-sensitive or shared environment defaults). Using a `.dev.vars` file is specifically for local-only secrets or configuration that you do not want in version control and only want to inject in local dev sessions. +If you want to manage environment-based configuration that you **want checked into your repository** (for example, non-sensitive or shared environment defaults), you can define [environment variables as `[vars]`](/workers/wrangler/environments/#_top) in your Wrangler configuration. Using a `.dev.vars` file is specifically for local-only secrets or configuration that you do not want in version control and only want to inject in local dev sessions. ## Basic setup @@ -42,7 +42,7 @@ You can also define [environment variables as `[vars]`](/workers/wrangler/enviro **Vite plugin** - + @@ -60,7 +60,7 @@ To simulate different local environments, you can: DEBUG="false" SECRET_TOKEN="staging-token" ``` -3. Run your `dev` command with an `--env` flag: +3. Specify the environment when running the `dev` command: **Wrangler** @@ -68,7 +68,7 @@ To simulate different local environments, you can: **Vite plugin** - + Only the values from `.dev.vars.staging` will be applied instead of `.dev.vars`. diff --git a/src/content/docs/workers/local-development/index.mdx b/src/content/docs/workers/local-development/index.mdx index 1d81dd62f5d63ac..c354b6110cb1141 100644 --- a/src/content/docs/workers/local-development/index.mdx +++ b/src/content/docs/workers/local-development/index.mdx @@ -16,63 +16,36 @@ When building projects on Cloudflare Workers, you have two options for local dev Both Wrangler and the Vite plugin use [Miniflare](/workers/testing/miniflare/) to provide an accurate **local** simulation of the Cloudflare Workers runtime, ([`workerd`](https://github.com/cloudflare/workerd)). If you need to [develop with **remote resources**](/workers/local-development/remote-data/), Wrangler is the only option, and provides remote development via the `wrangler dev --remote` command. - +## Choosing between Wrangler or Vite -## Install and start your development server +Deciding between Wrangler and the Cloudflare Vite plugin depends on your project's focus and development workflow. Here are some quick guidelines to help you choose: -### Wrangler +### When to use Wrangler -#### Installation +- **Backend & Workers-focused:** + If you're primarily building APIs, serverless functions, or background tasks, use Wrangler. -To install [Wrangler](https://github.com/cloudflare/workers-sdk/tree/main/packages/wrangler), ensure you have [Node.js](https://nodejs.org/en/) and [npm](https://docs.npmjs.com/getting-started) installed, preferably using a Node version manager like [Volta](https://volta.sh/) or [nvm](https://github.com/nvm-sh/nvm). +- **Remote development:** + If your project needs the ability to develop and test using production resources and data on Cloudflare's network, use Wrangler's `--remote` flag. - +- **Simple frontends:** + If you have minimal frontend requirements and don’t need hot reloading or advanced bundling, Wrangler may be sufficient. -#### Start a development server +### When to use the Cloudflare Vite Plugin -To start a development server using Wrangler, run the following: +Use the [Vite plugin](/workers/vite-plugin/) for: - +- **Frontend-centric development:** + If you already use Vite with modern frontend frameworks like React, Vue, Svelte, or Solid, the Vite plugin integrates into your development workflow. - +- **React Router v7:** + If you are using [React Router v7](https://reactrouter.com/) (the successor to Remix), it is officially supported by the Vite plugin as a full-stack SSR framework. -### Vite Plugin +- **Rapid iteration (HMR):** + If you need near-instant updates in the browser, the Vite plugin provides [Hot Module Replacement (HMR)](https://vite.dev/guide/features.html#hot-module-replacement) during local development. -#### Installation +- **Advanced optimizations:** + If you require more advanced optimizations (code splitting, efficient bundling, CSS handling, build time transformations, etc.), Vite is a strong fit. -To install the Cloudflare Vite plugin, first start with a simple `package.json` - -```json title="package.json" -{ - "name": "cloudflare-vite-get-started", - "private": true, - "version": "0.0.0", - "type": "module", - "scripts": { - "dev": "vite dev", - "build": "vite build", - "preview": "npm run build && vite preview", - "deploy": "npm run build && wrangler deploy" - } -} -``` - -Then, install the necessary development depenencies: - - - -This command will install `vite`, along with `@cloudflare/vite-plugin` and `wrangler` as `devDependencies` in your `package.json`. - -#### Start a development server - -You can then start a development server by running: - - - - +- **Greater flexibility:** + Due to Vite's advanced configuration options and large ecosystem of plugins, there is more flexibility to customize your development experience and build output. diff --git a/src/content/docs/workers/local-development/remote-data.mdx b/src/content/docs/workers/local-development/remote-data.mdx index 6b9090d241bf8d9..9dca3ae6b8ba8ff 100644 --- a/src/content/docs/workers/local-development/remote-data.mdx +++ b/src/content/docs/workers/local-development/remote-data.mdx @@ -16,7 +16,7 @@ import { } from "~/components"; When developing Workers applications, you can use Wrangler's remote development mode (via [`wrangler dev --remote`](/workers/wrangler/commands/#dev)) to test your code on Cloudflare's global network before -deploying to production. Remote development is [**not** supported in the Vite plugin](/local-development/wrangler-vs-vite/). +deploying to production. Remote development is [**not** supported in the Vite plugin](/workers/local-development/wrangler-vs-vite/). diff --git a/src/content/docs/workers/local-development/wrangler-vs-vite.mdx b/src/content/docs/workers/local-development/wrangler-vs-vite.mdx deleted file mode 100644 index ada9534bbeaf4d6..000000000000000 --- a/src/content/docs/workers/local-development/wrangler-vs-vite.mdx +++ /dev/null @@ -1,41 +0,0 @@ ---- -pcx_content_type: navigation -title: Wrangler vs Vite -sidebar: - order: 5 -head: [] -description: Choosing between using Wrangler or Vite during development. ---- - -Deciding between Wrangler and the Cloudflare Vite plugin depends on your project's focus and development workflow. Here are some quick guidelines to help you choose: - -### When to use Wrangler - -- **Backend & Workers-focused:** - If you're primarily building APIs, serverless functions, or background tasks, use Wrangler. - -- **Remote development:** - If your project needs the ability to develop and test using production resources and data on Cloudflare's network, use Wrangler's `--remote` flag. - -- **Simple frontends:** - If you have minimal frontend requirements and don’t need hot reloading or advanced bundling, Wrangler may be sufficient. - -### When to use the Cloudflare Vite Plugin - - -Use the [Vite plugin](/workers/vite-plugin/) for: - -- **Frontend-centric development:** - If you already use Vite with modern frontend frameworks like React, Vue, Svelte, or Solid, the Vite plugin integrates into your development workflow. - -- **React Router v7:** - If you are using [React Router v7](https://reactrouter.com/) (the successor to Remix), it is officially supported by the Vite plugin as a full-stack SSR framework. - -- **Rapid iteration (HMR):** - If you need near-instant updates in the browser, the Vite plugin provides [Hot Module Replacement (HMR)](https://vite.dev/guide/features.html#hot-module-replacement) during local development. - -- **Advanced optimizations:** - If you require more advanced optimizations (code splitting, efficient bundling, CSS handling, build time transformations, etc.), Vite is a strong fit. - -- **Greater flexibility:** - Due to Vite's advanced configuration options and large ecosystem of plugins, there is more flexibility to customize your development experience and build output. diff --git a/src/content/partials/workers/bindings_per_env.mdx b/src/content/partials/workers/bindings_per_env.mdx index d2f620835ffb867..ab81c5de358c569 100644 --- a/src/content/partials/workers/bindings_per_env.mdx +++ b/src/content/partials/workers/bindings_per_env.mdx @@ -10,7 +10,7 @@ | --------------------------------------- | :---------------------: | :--------------------: | | **AI** | ✅[^1] | ✅ | | **Assets** | ✅ | ✅ | -| **Analytics Engine** | ✅ | ✅ | +| **Analytics Engine** | ✅[^4] | ✅ | | **Browser Rendering** | ❌ | ✅ | | **D1** | ✅ | ✅ | | **Durable Objects** | ✅ | ✅ | @@ -32,6 +32,8 @@ [^3]: Using Vectorize always accesses your Cloudflare account to run queries, and will incur usage charges even in local development. +[^4]: Analytics Engine is supported in local development with Wrangler but is not currently supported in the Vite plugin. + > **Tip:** If you need to use any bindings marked with ❌ under local development, run: > > ```bash From d2ae2db327bacae43d933600ded45efe687e88cb Mon Sep 17 00:00:00 2001 From: korinne Date: Mon, 7 Apr 2025 11:25:02 -0700 Subject: [PATCH 33/34] updates local-data.mdx --- src/content/docs/workers/local-development/local-data.mdx | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/src/content/docs/workers/local-development/local-data.mdx b/src/content/docs/workers/local-development/local-data.mdx index 163eadc2b625a42..471ee7eeb76d86f 100644 --- a/src/content/docs/workers/local-development/local-data.mdx +++ b/src/content/docs/workers/local-development/local-data.mdx @@ -82,7 +82,7 @@ You may also include [other metadata](/workers/wrangler/commands/#r2-object-put) ### Durable Objects -For Durable Objects, unlike KV, D1, and R2, there are no CLI commands to populate them with test data. To add data to Durable Objects during local development, you must write application code that creates Durable Object instances and [calls methods on them that store state](/durable-objects/best-practices/access-durable-objects-storage/). This typically involves creating development endpoints or test routes that initialize your Durable Objects with the desired data. +For Durable Objects, unlike KV, D1, and R2, there are no CLI commands to populate them with local data. To add data to Durable Objects during local development, you must write application code that creates Durable Object instances and [calls methods on them that store state](/durable-objects/best-practices/access-durable-objects-storage/). This typically involves creating development endpoints or test routes that initialize your Durable Objects with the desired data. ## Where local data gets stored @@ -151,4 +151,3 @@ export default defineConfig({ #### Sharing state between tools If you want Wrangler and the Vite plugin to share the same state, configure them to use the same persistence path. - From 72c19cad6e4a2c47a3813b1ed60a1942e4d050e2 Mon Sep 17 00:00:00 2001 From: korinne Date: Mon, 7 Apr 2025 14:49:42 -0700 Subject: [PATCH 34/34] adds changelog entry for full-stack frameworks GA support --- .../workers/fullstack-on-workers.png | Bin 0 -> 168317 bytes .../2025-04-07-fullstack-on-workers.mdx | 38 ++++++++++++++++++ 2 files changed, 38 insertions(+) create mode 100644 src/assets/images/changelog/workers/fullstack-on-workers.png create mode 100644 src/content/changelog/workers/2025-04-07-fullstack-on-workers.mdx diff --git a/src/assets/images/changelog/workers/fullstack-on-workers.png b/src/assets/images/changelog/workers/fullstack-on-workers.png new file mode 100644 index 0000000000000000000000000000000000000000..e8500bdcf0572ebffb2b0d25098ff997d0252454 GIT binary patch literal 168317 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

jZr&po8(5_#KZuhkynYBhU!7U z_*8_ECPIK?uDR{oeax%|BA5|&nC$kzG{vtD_%bP#U7pq5A;CgmLJ;5fKDV)OX0J#g zcNlLGXde0(n-xrI(@6k$n?6()1E4{PQBf9kF(QbHzn%Bd#=;l-K(TBE41>Hz^wu)s zUKC?#%Z?l*yJh)y#j265^p_ln-B@`2u0I}7@sf4?jRL!1)@;%|mx6+UBM&Cdz3osbQt0S5>h?1Ib{aj;8} z0uU`Cc>x8tyh*h#cQ2*p%GI0ua$@E#5Q`UrVmvY6LY`*%(GZh)E~6SLl*vp?8MUyV zMQdYjaVD>ooC>%|axO|QT@>Zu3TvnV4q|S`2g6k+SWYnjh&S78`Lf_tt^{ZBy@HRT zCY9MZ?w{~!V0XAORt@`^^@4o49 za&7CO0og`4b}}~;!#oY|>s@jhC{F_p5SFJWN0rn7b}-{zRL44ncoLG_vh}2XTz;lC zfLS{%gqYJ?SSWZ)jtMjfF?jM%;@D|_)C8xtB$Aa*Cvp&iBpLEThSjIJ-XlN}aRLp= z6?2o`l?O62^_H0b4OG_f2YY_u!V*zzPj$BZu`Z=&w~Q)6GTc`6+y?1H)&p~*Df9w#3$ zP4?-3j*!oC4J^Fm0;x(KV>%%#B#sFrBLoq~%&T;#Gpm7UE1GFm!C5K<*09$a*Mss5 z=NSS9${SNEAoz~>6N>DIOe1tgWtU`iXW+k*@?~S;^>-@#ximu>fJq8C5a5SmIqar9 zkYN?6C>8<^1kch54eRFmrL-i4wSdZB`79MfLSRndG(bW8<>A1%;n@YyF|I0+ftIjB zRcw+szgb;+t@`JWl^}OjjjI7n*v3yee>07Hff`IQ2M8PNf;6l+NzXA@Bf9o_=Q*Zf zuhsk)3|PzVA>^^r1U@qTB?nKF{1^#XK#-`Hc|Vs=#sO?mh3@DWHDxftCtRA>R%+uy zY9(Y;#0f<#tqGzM_gPa7aO65OJ`}Fe;R_^o@$vIlT@>m9Uq zv7)qi;_A@y+t%E&SAN$;DVvKe`YLevA3jGqcm zyg;3|k%u&Wb9miNv~`>lpV&4U+qT`~hN(n@x{?f#P?gV)$~2`6NUEq4^VqD{t1Bko>J* z53il)kz~4%1CHJBlE?uZXG8ChTOvb*NWc8Uq5igqhZeMFlA6LqiIbJp_?GNq7eU0= z<{vnqW~Rp>$YZaz+z}fq`&f)EGS9Gk7)~e& zUDut_MXUA6`~rTa@z%P}shS5)WJsF3h=^Q)CK$5cDcVk*o2467g<_26+7{YxH4Z&K zjXk$zOt&z5KqSlu*~)_|0ej^O9^KIfn~H!<`1`rvscv7JE-B|A`qH2gp@2f()mkC8qD|apYeC4YE>bKu5qoM zO9U5?ERDQ0@#c@%(Z>P0l7+C~-XzBK+ghl5@0Awe?bn&yCHa~53e|kK20`=&JtR`lcW|4%s{Yh4J!bLp0I-72AR{I56Kmyy&>5AlGL8biS(8Yzwpqd|rYy=+J z%u87VVo?>!0A_D-FRsiwSGDRIrNQx(q}C3rYFi#Fuv8N2lhH}tDIiX-xfN!yQcJ8u zQ~tuQ+5oav@qUApd3g#U`*{S-#(4MG*5&WwON9?Mk zE>Y;ZqjZ$!wlq1|)r`*IBp=4(SJxWbQ*H=l*wK#bUsj)Jnvb04An?9k$bR_)mx-AB zTxsN6;&|GZ#F$$^`^$`O-wRm`GCyH;zkEMG%R*W+g^F2~1e@v^04X1j_$qEXuvNAr z?9!$a`qk-7zw^RF=}GJG@KQAfZkMaz+uQd}>o?u4d+a;~{P&(`c!|$=gl5h#{jBlx z5g)4oA3lz*FXkiPN4AiNK&AsY`oPhx34~uuvEUqMY3I&f-_AloXc%GW%Zfo!O%_iM zL5>_~d6^J$frJu-97ob91Z|mrQNjV>-9anmNPuWg>{8s>Zaj_MeaNQXhq;UFBN+ah8^s026qG_e3w;8fMYwF4pnpV!LT8>f{w=jy(pR@*g{GG9tz zK$t}eP}V^)`&i5dU)tj5#I{%p@zAO2XMu>$6oZW$M`xT(Oxej}@ZFqM!f@MAar{H4 z1~mUHm<} zIl_1J09`ReRtlWx&(`mL3xbCA@o!wt08eX<7GP7*Km4Q#*cIoS z6d3yRgT|4Wdi1t~!3;Y(tM}c`7YJ_DpK-vY%25{ay&wm-uguh(wi?K_zzG3ZDXhp zQ8Sw=XHFas(;U0Zo(YtHb$bS|yDQZ^x>c8i;=ISoRoF=4uWlf+!jk$$Xu#exz+MuUR?nWYYAWcuXIIy_Lk9i<<(vxpfY@=%V?2X7+pDxLQ{S=iXNUkdzblzYppcvW}qwD$C;q>vJl6hJ6$vy#4 z5tfwWJE6-b4>qgrB03W7RZ%^G$rk{0NAnLt1P=Vo5JS`{K{5J#E`~G80yxx4EW{xb zteVj%Zz-vO-#e3igrU9ZzMEyF;&g*BA8Un zj{`qBW2Tk9hl4dHHA&R90cB=pxm(dL)V^Z5+0rEoEN>CMNOIi9({qABf z!ni)AL&ld8r-cO+gP0NPe+`x(Ovs6(A@IBI15e!vg^zBFvvbeE(#H4qJRbV}E)x+# ztry!lXQSN5$RRPlVx@bQjrT3vA&u4o@#K%K84@CpOd#kvI72bJ&S++BVIn`1Oo{+b z!Q3}mgI<+AxPnE}Mzac2{RC=GXIE02s-Y9a zV4ZVLqc5Gxnqf_hed>Dbj`|3UR^h`s4O3T_Xo;K%>J+m~v z)i3gkcsdM?M{JJ?0PW84Y-YWy8e8@X!W4EaleTD=?{G%h&5m^A^V0DbLew&LSfkpqlY2 za}^Yp#UYk@fliJv6wGnwOUQ>;z^S;r;>_1Y+7;%fzj0-L-KacV@JEfRK(98u=r;-r ztLbyC-EndqRGDnsiw8Jw-hHh?ql{qBc4=3Uu$*J@eFQTzpQOk8gF^9CkTW_#^mvLb zTW=y$Z(l#l8L6KVu}Hy^gG;UIz0RBGdyd_S-Jc`dhiwl!ZJ2nY3?xc1xNn5Piak95 zMO}ZJ$X#bm-IqeA3ZZHB+AvE?nS`Jo(U3S1MfNnlA;eIMVGiJVyK#OzhK^CWW2=XQ~QLHR4O{ZsO||@hQfV1UDwl>TShkb zL~)Ilh+Ts=Ppz?22-B3vtfa|p*24qi-|uK;J4UxeAw8}D=_7HZsg!Sg^MUaXc>+Ag zC_ELeS$rP`p4(w|uA|H|C}_|z#M-g zn~8T>fTB*0^Pxr57w78{$9Bi4y?;C}4iBw$@6$V;vmk)568^ON?RyXTkY!v(#xaOE zK}AZ&$h#)_B=+POlu@UyV4kQY_3YCv{%+)~B^9&4$WqZc{d>IT7rH1wGx|9A)jdn6 zTd(s5#qNUNduE3?RglmehK~B4PT{RLYN95fs_Wgs?K-dZ6y-2ZSpKlrY!tH3OfQ4Q z64HR9dFF~>Jst{&g74doZ);OhOh5R|nIgwsHPIPFoS+@09GURR>e)KfET4PKw@Yxw zc#?@#8|d2%+X-p>A+DjzQfNr1X*V}xDo9;gXBw-KuF81uqa?mWQqG@|sXo+{b)qF6 zgF0FJ2evBMg1wxiUFVN!yNLidO5*B8D(&W2*f&`nwOCCV+E$F@yU<+<&0>GP5}D`v zW^b?-{`?*;F8#NT_q`_#d>X3)lN>~CpwDSw6n!kLVq6D&ifmDu!PSolRR#TGb_O>l z6qO=oGje)|F;FeVzYjt`_}cMm#4xu1?FC43pCnftjCN!i$W-(Ue|{Gs|5boZ?I|a9 z9)=dsF|-D-jG=?;a<6JVWcXwMHAwaCR=lhF*-ej>zsUbu!tE4G)Z}UCUl~`{ogBsy zGpeaL{v9Wh069)>|oIxcU2rIPj=U$ha`S&pP^!h(o5vD+e;)1|gq5 z_k}ie1p%P+V`z;FCt=F2J`kvHq;WoxgUp%8DlmbKiD`S3VNV}mf^ey~%{JpXcu5NVff*f-H zF7l#!Xce~NNHU+OtlJ9aF*N2JqPkgit(s~asEwrpK7|^6 zED!%QryQ5QFhGJdUJ~igx06VzJM<((!*3$3bE=u|+Rhf*{=5kd@CaTZ&}=COh0dno z?dA|Hh`iPDyXrnLp>5rW{jrqEAMv6_1s>8{Z017YbX|X8$EI-b33CzRHD+l9qp1&L zIMLre-y6+m_|U(oPGr-kV~dWgCd^;~3Rutb>6ysRbxY@<00*bDMZ-qJ#~i_ttOxr} zkW_kbP@!qUy>!2ssD3)w?6(jQ2EM8is#6rW{hFT(tV9>u{HEOmV@+vAW;QvGGYNpf zsN6*Yl?Ap0%01y0vb4RG_1G^r?OsWo;ubE6>*o8Ge6^g~tBL1qY>CZ~|3#q=Nkhda zW_co4X0a&}5gv++#L{lK@nHmyRNBI{A`>anBhFOYao!ebN{*vK!lzqY`~z_mtCc%6 z^m@_*{g6q-l#j88P+bWkACw$8ik?6<6_CRBX|On_PKMMK`=pJdP+0hKVtC4`v9WsM!-Q|`8X3|dNnOti0eQv&$ky^A68rbZFf^AGmn;5Afh9ueOaCrtbpF8 zV<`jFo9RAxdZ-T`nfh~TD|XXs@X0}{7CsN5u`wuQ^({=b6bty99EvxB|{>^vhBK0^%n#=hrUCg zqijNPOekxx<E`%u8IZn_x2^%8|KSJG$_ z6TC!TdmXx7mYx;Av#j495}EgvMEVQM=LEihfd9!#VYNZ#J14Xr9O%} zBo;Ct9)}6^v`I)Eq?1$6G)bJ`G%I(m*9X%kp$~HOuN$&}D@dHU$;yw~foeFaqNP=( z3Vrp8f2rOz)n7QAIzB~cFDLcCe*K!E^)*Fn5k1F`!*L)2^C;JcgYiRgz+Ii~^!`6YI3n%XJ%!h*UTy)a851W7f z9klcnFi!C8VMyGGT++t=id_$9a=C@9X75`JlGj%b(+K7(gPHl}F`l?Rq^(|4p0{lJ znD6b|Tvuq%nZL_y5S3P#0ef*z;cb(hH`o9W-MDtA0Pk#7$ZEL0)}@lYW0%?$5rGtd zi*&c7U{~?-MEpLvvYRlWws9zxdrp2-%-?8wy+N!nz*BcNV8FNRgw8g}g}BV`1Ms`d z#FPQl%WBVr1*_!Vg9h)>kyaw^8DzFbGN-_)>AFVpQ?YlBcUIDlT$06|VQDV~@ePj6 zWPYBV7>T@Oh*^?o`Jo-x=xXV~C)bna8LR$UVN#^vWe=8A`l2>0cJ-H_2`cGEo?qW?Ex$lvd#>!1AE%1C?SEQu98PTV83kaXctS2Hm+ z2->}&E=NaDWSS1S0sQ{QPRQ;vZZ(rm0bySkc)rO`LG(!({IysX0#bZE^Ymheu|$|3 zYE-|>%F||O+p#vq<}~~kZ^&won=Pso!&53;koMS8k=EYv9RdnOYDLa%Ept&v&Y{VE z1T)?n(m2_sbx~b2>DK2@ry3WI#FMByvE^TNT{bBmc#ifjCY_w%;FRg+cUg;+7!B@X zwv?Ay2XoypQSqWm=1c@nc{q)^kPtn62x~HGRy*(@t|=@gR8v8SdPA2tG?49YOsGb< z7Kc#>7Os4mH0gmBB>;AC?7wk!B__NOQ_X1QE8bLQf(ywL)|D$?n z=to+#%ncQAFtBti3Vv##DCUr(1hN)JN7WGQPBOLlkU;E+w-(EC2J9P!P|AlBHK<;m zrk~kxkwv5Wjbp*>K6FDE3_P6Y`>bzHL*Yyv4)wtRtL5e>M$K~U)NRr$2RnBgd5TAW zb13|x#uI>9gO!=a@3=L*Mju3ag=;Vn_lqP5OgPdYwHkU%$+>B=bmRkn{w@?2Q^xyI z0qr!Qi8xlED9GQo0RWK%=lA1`e|MZ85(zeIr^KaFR1*2x_j-z=!rVmWoP0t=my~8= zZO&W&G%Y%m1T3>olH6)tF)^%|43jl$`!}>)tNyefvphxuLLEd-&4f&dbg;C@-&2cR z!M;10w_uw&Ucc5k?z`s_eFCMh*Df-%QZm3qy3i1)+8&SogRtKCp6wS5Q&6c&hB^Gn zNv0mG1}Y)T(K!nC2D9gt&=B?p*V+b`4#jK-dwiMRZQhHEa23Ls-TMu8i2g#NwAfR zj09$^GMR2u7kPxEI&CPvwGTGLFN-;r`F-$s%mWcQx0SKohPNV)t_i70%JKEq^Nd}s z6OF_?&LEt`7e^IHF1o?cVS>EydioGz5d3(Oa4g&FdMLmAuVs+0wV}o9w$E@sh6HKN z)5XunwGrmuY=mOy&D_X?lp}TzKCM=>%DK!!fDQUR4H_b8nro`7v> ze%&ZS4fbkc)XI_tedi4}=Ov_!c)R^VHRyk8J>pH>m(3Fn-GlOUn6?lijEb~eu#X?T z2hN%0^h3~n5k=IfQwYG(MO6im=&NL1ug4;a z7S0%U@{Vh+oe3(G_~QOH!oL;TjT=%-9LKgVnWI~j7@{qR`nWARs;Qp`uMx1^I=6p| z6BZa(9~O9M3cY?qf8j=KOKAAs`P0M3^*|sv&ZeNyw!8oDRkc8T_J)JuWwpVM$v+JX zsqY8pmm0IV8USWJMy}J1lICdLmBSh6 znK@gfY;DUMfA6mzQz#JB?~C9efR%UcnTpg;>Ds&cD^noC=H-+izim!7FZ@BM6{qlY z+Wg@orEgfus%!>rngjd8rt1eTOL)>An#}z4zI1&*Ah3)iP8DTFtl{a z;RGF4|9&TBZ~?Ey22ED^J2k2qT|xEjK_#GKaI?74|AxU**w70Cba&#IV!1fN_M`>J zXDWU^Q*VUh>M#W*KKpX+8SgE+(wgY=H%oJXQT_l5+Qye{HpHFk}_5zG^V|@PKL>C5cEpkM~?3ZujJqTr!esv=sx9k zk>Wn3LG9y-<*tl}5cMtc#!M{6a&|<7AbK^{eI^8}6;b3VB0f|6a%LdR){*IL)zE5M zLPJq0A0L($r%E2}`sixiD6N9QSF-z^%jIgLq;S$OAf^5AmO%uhr7VgZUW)&DA=~?Q z&-OYp&AQ%k9eP9fA={Se0tl?-^EQY#sO<*|$Ooc@^nU+X-vUSIbf-LZvD-&j^c4sy z&H?0!cwjaoS^=4lFR0AbZ`k11=jXbjb)5T#2%+VAGCd#STA-V!(P>NqWY#lvzQEu@ zd&Dw)A9)GujvSv`=P6)TaQ{1)l8=>HiA)x54o{?umlt>Z=<)L+`0ImW1uCf;Z#YG= zjsBEj^OS=D1EZD`j)tNQyiB3fxf29Rr08r{g3YJwiIf6L-^6v-xB_EGzhDY2MXwu4 z?I_`Fo_C1$V`4Mvk(zQ*AH7A{5xo$VRz1k;K6_F`Dapilu)s5iHy}~&Pl5Z?tf%XI z*%?IUU;{%scg|E#2xnS=^6n%kCUjAgx1{PTNl}a*0ob0k9QBMvG(^_ISS5UcimJSQ zN8SS)L*~y7d_)ly8Y?N0FvvD->1Ofi81pe`cv3b9jPid(S*f9A^Cr$Jd7=f@BFGz* zG1V$cU4FyTWeP;Fo^!Iv|NZ^3h7qFg@A5OJ6>@@kNq&cyNaH~u>*Dr6U_8||87$L6 zOlV-J(t9rjBxoD~kfmc_yAYkr_9KFx+VQQh*09$0H!La)0VwWR>;3XJr3VyTj`fvV zrl;u@bq(4&ibaC`#Z^n774Rs@_HWz7_rlC$lmd;Zj@6wlZ5U*Y5U|VmakOyD%zi9J z@JE48Hg6_2=C<2cGR`wQQ4-I~Y&!K0we3*`CE>!&(9JMvg>Uas-Bg2|qsF?dVFk*> zRDVTx#tsUn|&ZJPXVLLGZP~DYyC_92}36L^Buy4kl zIE4%?hhETUhcT)YTTV!|q<+3VpN+W8#*uK-PIG>1H}QH@`~uMz%`Wbi4OeUA_i}dN z$pP?=^9;+MF#Ydb3UgA{=Cns&|CAz?t9JM6J(v~KZ~L)S<2GD=N~K8RdF zhF^FaeXOmEZ!0TRoDac*KqI$?pg&Vl$}cDTEsYu4Q;TTykK)of8!In(8uxPFy?3+v zsdyO@sO;Km?ziq*AlgSv*N z=t|whz8(MGqBk6dZ<%nxpqL}BqF{PJga#P5$)JIu@5i!gnA6d+BZ3by^rF(F;Vy+3f} ziolL6DHP(=Fc~z&`=cv0D=Jod8K^fGvo6ftTPe9)7cb6Zh1HbNpe;hWYOBBuQ1^uR zp*Ow1`n`0&+S-nkzxmGV=c>V6-g5BoKE^8~H0U1W1-4Ktd`B2g`o zSx?UpSS=y^4fFksmIomiPr@YILOvq6-8rfK5>XiK^s+kJ3(LjCl5))<--N_xO!%c} z)T1SB^Dy4z`%eW35J%-U>;Or7w({G8Yqi-*l_)5nZ6)eFn7hi@A~U@qE$df9qTzXPj#r-vE>4F8i;Djd5@~MKdxp)! z1GwsYnv_;pCK$5$dmYsSx=H%PAbl3zn^bf$C&xX;07)#37*QA!oDf7P92Ef*uDd^$ zE_VyWg2i-@>8UYbxlV|M3r4u&9{yz(UzVIHd4&CxMJK{MnWaUf-=gmsSZPFGTbs}P zm2YGUR30kDgjpJ>*L9%5QH>{hdrw=NQWmL`-64DsgQO=#hLV*}dDB6a7l%q2>mEh; zI(qpfC#uMu)xCm2dzZg zdleHkNq+E6^L|huH;nRY8-g(Ei{gvi^G)5b%9`QpM4g7!S?tr2NBX#Xt&3|<(lMdI zE;n@mug+G6ta3U(8+c2L3Q$gdmh!_pX6k(q3!Vacux{S>@nW7+)!JK8>=hW+&M~f+e8wTS7=zV zF*>|nN1C-W-$ZywxldwK8=dVg>plQ1M0ZfG2OS0LG4Ph0Q9C4)IHYpn1c&#@G=9@^ z?I%5`_Kv&IO9F!a+1h|5%PJgNjt(L(Q*<)Eac4dXnr6x<23uq813Wc|LY3pXuRm7U zko1j>jS>-+nGt5l#G@H<&aT)MEF{X6gO0>W;p&G)aDF81HwJ8)2N)fId zC%{j>Z?WfeTKQd*VRy!eFnv{4Y%#0)>(|}-Iu7@GzdeKyFy)On!t9gV`a#1XC@F}b zyYhE%XPyNJt=;S7i)t)?IXLaI?8GG`8%}R*_|}Wm4am#oJBYTC$-0k?T?LE8i2OC@ zPaObvtNYAfr5}vq5&%t_1_~c1NPHdIEZ6EM=PTEC<3mX`UM;#MIc=ezIg3&HkK*A> zz6d@8_9nCa`b?5`I0MLXC2+aBrNBE%c~j&Zn@HGpsdL@FgDbC>&nrxie4zslRKVKq zT2bV392@t}D}1fg`1Ksl9)MF47++y-_@!9pT0gc``w*-^>$GWm`Buy4wqp2acHKGVKp!FJlVrp({qx2U3$lHv-uPiE6F6q;lB&IbVBS=OJm(sqHyoSVhr$G zMVV5@T~Q76q^JrA7PZk4u>#`llPKpP3(1Vq7IzN_P-p%95f=U3Sh<&0vg$!C&CzZy zMrG)%i^OBl6@jFB>n>b_C!a1zT?!gvLcnP1(Wl!K_+CtI0IwS!&pMu(Rr(JDa~Cjf zniKEbK?f$H-UGOdpJ-in^V;n~+P$*$e{Mm;K+4-w`T9l7X3BhO(HMJpM_vR!&O*=r zBdNoczdYJJ{YVqxCafXikb?l3FQ6+Qro&x-;}Rva|0yy2TyZluewglyTh42Wwv*j) zQ;V{@CIW_Al6Xoj#s7GtnF@IUG!Byg0ZWwrB68#Oh1~aaJDZzQk`%Rt%{038zlEn@ z;0z7;snZ}^Qz7dhFr&e!p-3*5}0foSnCvW^P@W<1^7y z`?qbd^KyATHI14$;~!$0nlC)+FDr|~_%PPOB2|Y@xIVq+hktoYVh|upLy+D~Pxg}N zIHc+CoK-JCs6B>gStVRtiu=bE>av!H9U`e_NfqJjyBi5#AFJ$y7&3)|ErD9CVyuE> z$d47~vQx)Rwozu;SlQI~pIL@+H2x6B6x!&l5=9iH2a&r>EuA;QLFzNevEW%vQZq+$ zSb{v+F~ULjl>Qq_4UvSMb4mT)@h}#NU5_)(?~ttVmLK(({LZ^nK$zl3FkWx^Eg%5( zh<@w7`<%kU!}&LiAa?9(ZuhT1pkb1EUq0_D2SyIv8Xr>Do@YelQ5<`ytY|8Qk@rGm zV?}a=a6)DQN^Si8imvC~85rveWlw;!65)a^i1XiLcEmO4r0RN6Z}7Igoe-1U>_?z_ zFnqj+eVwPhxM?`NB?RLVmfm58wgXyj%@q(J%>7$(him7UHi=?;P6d;z^1g?3pyv)GmJyQXqWRff8XGjTMR+ z8J@ypuT!oftG!h&+X6_NkgV>7V;B^JNna(}XdFA|IzAjMT%Q8H-U5m7+{bY-iJ+`* zrbgap^(E(ja?Z`G`4r2IEWFNM3OUM0PFhrwn2C!O^!^Z{Pgq+zN_CAl)Vr6o%44PD zm4(2|F`oJ{!xqsfAI8nCfLq2Fm`t`Sap;psZl5aMk#FYUO4Vf6-8hYX@>m})ZL!FhP}QTte?QF08Q#;pVse7 zhRx*uVEr}2T@PF`^6mkD_&nt`y}Z z%OsCLWt9L^*O{L6Ini41Gm2OAA_RhTRcNGX@$^o{}Uk`Dd_v__+0i|0yOu`7#cxAl0S@dOz7Zi&C3_2{?x+mYp{@mLtAo}K6ptTs$ z=6Vd}vhB-E$2xqaE7%8$*^4pG0O`z*x9#?U@0J*ql8iD zgtbsdE^VSjrS7Pv;aKwkUyL^7@9r4`9(5|SfZZCJ+e>sPpaCIE9gL2Vory(S6UOGD zVCRW}5UO^>B2_s@T;q~4bgEp|mRh)f65o2X9!koa|09Yb5sG%rX++#iM40@^VN7aSc`jTd5-WA~>83kw@)3CDW!gyE?*$el2JS>3uu*#+pvCveCH1Zi^gC{c zEJ|oP;L~Pl=-6rj1nC?E0OmrMLv0wbU^u&Pd5g@2=<4~%#2yMPzvNdVR?|v46Epj& zJC=ywZ$Rbr3ziFgg5lUnScYn*d`xSwkWel>@75N=l`^u^gYz2)lw~N!X)h} z7e*VSP8;F!kD}{dwRIXxoM}>&)zW#noG+{AVG$6cEJ&8#*jzsQyj{AwNghk{9Gd5U zS5QkBy%QI-_!WO(!cyvFQ1jiCS`=uEqgR)k>oqFa(50r07?Fe6_E_#QaNWk+adC1_F3gBDFq4KRIy-C9LnD)a1T$P@m$DaLoLM8!gP~TVedXo zAeG+MLsQP8{ga6!VcTGweErO9>b>!zIrG4m@(&0L_uIq*uD;|x3{~HZJS)J>4GXSfNj(~ygoeYL% zUhcrqjHBf;70Baw>#fV{Sm5wC;eAO$NfP395QMi&&GrGrGrbUv&ptWk{3FNIRsZ6G0B7H@U-hb z35pHD@BE=^**XM?M&vl+mou~#*@q4R{FTVak}J>4Jc0) z$16`sl08}-+*p7GbpU7^H)T)_UoID-LutG%(hvxd%IhPLxN$b``R6xHyIw6zN&=T? zU(hWC(Kd9$W5Qoac;eQbn6rN@-w(5_nzYrju!TSz3D$d10VBRdSx&uFer+7LEG&7L1yAEGd%|Lq7{bHg|yw_n*Lx? z0jf&rcUE~zv^HxMSeVgJIw_CcKr^D$c!gOvzr!{M3eo@Is=^+(@|SH}U2W<7`HC5{ zzD$_npP0ai8mfw&B4SRE@bGlHL@CqyKAi8VS3@I*(cf=rUz{tv-*h+c*-71mlvZdi zzGk{gcQgOv-2IFQNw=)UNfQc1APpbp8zSb@_VzUC&CpI@I6e_~&0}Z#sU9OTe>aB>kt@CgO|epOj|NwRJ%L zajwP%81as^ikEwJF0no1MASg32Pf6*sO z5n?H*H!<}f?d%BUK)Ici0}(3#@6*=~h`Db_b$q-w)7TTO1!Baov%&(D&A(&t(KD1N zb29fNk!^SFUEj?yzsj-bDW~0vFyf7h^bXlk8=37X*stqbU5e$v2aGYOq4KJl@=HC^ zRTgjbvGRfPxN6}r0tOOXqOKzisRXF#3yy+$te6C0=Pg!r=@2XZRvw65mStM&YV(sr z5CP3KASV}xN81`d_nAxoC1Ic5(&RE)fa-f7aBJ=9QJO^D*N3MDeAoyY!YPYES1pS| zfU3IT#e(yK+Ww=q(&hhF3WDhSM;We(V>~{S@CB{X?0;DQ^Ks@)a}1Da+*wSDL49|# zflvkdOk6%ki`@=oIkNF=nQecjegVVUBeGSouT6ET&LDdBVN6L1rdwty9hvw&NS?4yMRSCczP9cv=L2;cp zLm2aDK)DD*UX*~P(h2=?Ox0>Hn%(d=H`~l*J8+VCTnZOPKhZ{!{tG>}PG1&5@Nd0j z%!BD)cH=pY@PS2ah&7Rc)aEM&_q4V{;wZm4Kgerl;^9H#8%@|9^Iaq6;ry3It+U&- z2(Q-&KHE%Az52o??j02Qzs@`TMS1Z{%OBuHdAT}6)xgE51~epaYVsAM2$2Awz@=XUZxm zW*5oG!WB*-aa~9!#dzFLpO1SJ`DjP2Pa9Q~Caai-s^?4TgZWQWg+8?(3q2uGyI05> zO!D^Q;ng@`n&(-tk-He5mnRAd5)jivFya``nA(MA%;VM-#rZQpxZ^>VFGF0l~ z=t>qWY1pV*oZx9KhZ3h6UEfR#?B36yZ;!@6%=EJ^c(<IIQ7dzmo6%q8j) zo_^YkuzL)u3wJNNTKpo6CGlNC#<9Twt(KbPqXgDwnn~z`&+wiF zPGCW_vXYaj=1fl|IAN+uPo4-_T>~C(Q_TIBW_m*@aq^A5S*pa?Lz&ylSXQs2dRcj4 z7qw7(=N|V0MqolN`0i4-D$Vc)AS%Coe$*(|*=*kU9Ky0>QH>qfAFRuHZvC@mt;}52 zH)jn#&nP|Lgmx#z=z7SgjvW9cb}4u&G8f$ZG6mby6?e)>@u&P$a5QvnNWhIWCCX^B z%aKWX-9#_w{X%^6C`E%|7h7huK1Wm!D+zz1efqMh;lIzco>=|>!bGAxdC>AQ_pt(m z&-6+2N2j*S7Ame}vRZe~JeglgN^-7bF$#CDRZT6oMRK3LtkqVrdCU!M)JgQ{n4WLl zQ(4PLAyt2gokCtE4H(ZBv;*2UxbtEndZ^))9UM5ZGcIM)lCXOOWRL=>3_iz?hX217 zKzVJM1lx*f`yEMhM}O7vwhG*W7l9@M>L}%`%C8uI_f`A0skfIfJb72URY$6^GQNj& zd_D*MtW%C);7qaUeC(FIT`K?W(h?CVe+XPKoR!3XDdA^oKam);(*M$jLN9(kJMrZ# zX!#lVqAM_5a5&#lq}+Q2MC_-sSw%h-4$}fQAd0lUkiG(D$(a1lc(g8R><7m1%IPm( zNxpy>mo*F8pK~c* zBqu`MwV9^(@g&=9qT56!)6@A8QQc=QOG){W|4`!jEL<0dVHd{I%~^cr0`YA*VT{jscRLTkOkYk67|+z$YoR) z{P>dSbwT*GYC1Fj&T4Xq9x5e*`YV|b#KiSA=#Z0Za75Mei5eEf$p1tMrPSV*u=v-E z=t4Nh=NhXIC*%Jvnu>$0=?r!LqJVw({r0BsQ%q~Av5w-@5Pkoz?q?*Jd6RLG$|REk zNBV!G2iXoH!Q2Epo6cF$-OTQpFIl61}PTfVAXa zU7LTz+ydP55y?$hH)WawiMnt>$paPYGs)1G@^3ULgyGb8!Id2iL^HjDIJ=Xh9wyvA z*MdS)JSG{NqCYwlgtR27RA6%RSuH|Crl_}3Q20Ye7*<$1F%q;hS&K&~aSNb%;|a+h z2p+;o-Y`YfO{Y!-J-&~SS^|hNdAMMdg_eWj`8r#VlP9ta0_i|`ss~BqY=d3m<;^28 zp`Oa||1}9z<{Qz$<0Ez724wkknUSo>5&DFh5;ZRl9%TJn2(`KLlCGCZeU@%US^`qK z!h(xS7!=O`f{a@tD(L^_rH5!4q6x|Wv>!Pyu7_2t8A*EtO%xEdHCgl9CU@Vp<8@sU zx)up3<4bMyW9>Da>CTcrq)2TU5EDT@BJgXVzAB6mf;t7>9jCBW^c4<2$qW&P5JDZ! z5W3OdBe==X;P!d}>fg<~`M9-Z6Gqb3V|g8iEF8()EZk>^u5O;rTqMJ%^lYS&2HfYK z<^+7{{NGC~3XT+g7pe3~$IYm?KzxIqMVa3nlBHE0;2gXqBT3+ccTW?{wrtjJLS}PF zcc&D&+LRzjZB4wh2iC_hJm_ZH<4N+)=}ENMXH7CK=3VXE z&>&JyIIqKS+0V$nzKi8dC*P^JZMOC^xw}(BgMSnhWsLw3d1Jpc6TO*cRQMF&0Y<1; zCRB4EKr#eI`*E@|kf?np5uBs8U4;&JHPL2`JKU9pW|W9zH} z92kNOIIV?c8mK{N?xZElI3);!KLHc$vkO=r>r-2*O@<2cZ&Yl$BSOBLxlF2Vq;DKh zeW}R??fU*Gcfg+*oIvnk4f>C@6J^Wi`ww*xho0OBQ12DYo&x(EqPIe@kpzPIz=f`pbF^rw1%V7}itK9iDv!Q&KfCD&d9$GaHj$o8(-aLF zc=#E4Ou05WGBe@X{LyZvLxrsBH|%&nod3&) zsR{M6!>3?sbj{72oQyjCT)->{p}B_V!Yj_`&9hG|{dHea^=n&&Y9@>`JwP*_#s@WY z$n6jGIhg?I?tmh5v^tjIM^`ThFMdiw_}Vnbs2s6qM!9k%tw4B}7c10FTv?IsQ#6?5 zkufGd|5B{RAc%sisf;)=JO-HzYE0EU9Vdf>H*#>CrNGP`U2$MGBwh3YLzGE(A!GLz zDxRDN2MV)K6Hic9Dn$#G6}syn|A$N3wAYCZ8U>)?_v&C7d(c zXfYhr(%XdKNcfI!13?Fy=h_4sLWKio zslN#hg(;)C>#y%MW%P92ncQp2ua);;-js|) z&}Ligh1A&T@|^*nc^gXRto<^5?BQfc+yeJ)`;$x<+2%WgJhJ(J$-qhuZcjR5Tq z7G**Qg=~!P5%^g7tKdyE#N+L8UWH`S^SbjehRwZA^%@NA1&H{@tpWOype z?q@2wV@Ft>X{MGsypBa%T1@C=%5r*F?g03P3u%@A9vxe_$uHwWP^k|BJ<(pM=ifwK z*h}ZnUO}-xWhnFIh*~MhIU(X7m$61X%Kgm&$l}e50}z#mC0&ABo=T(`_^X;f%6pQ5 zC?IQo0vRFdjQbneF5a=m`U=&Iyk|{xRMmbT-Bony&hI5DkU)s*}r^ROsG z)#7c~{6FJ=gZXA+TpTin|kLA&IMmTspxRO~Y;8Rz(qw5Uv+@25N*5-Gj zoZIGq$cVVQ@ZjArf$(2b39X|9kiy2~@>@@C%N7<(%OvK0TGl<3@JE<6s^FixP7`G# zR*yyq%+$+|FCOm3ms$Z%Y4$mqE6*|z?Ti%L{pDyjh#Alc3;ADR(}7DO4@Z^T5kU5p zCwN*FlRkT~`rZ>~%tWk(sh_0SMnjJ$J3HoETWLcXO zGBz`EaYlO9cfTv&j_Qr7F-jR@z5oeyxqfq>Hd#h997Ho9do&~JLdGbfZj8qKkL1v< za&~h#4>@?-G1cflMWXz@iGtpUDh4FvnDol~Dc&xYjdAYXb4^k$Advp^1}dMAMdL2R zu5u0JH2QvaD1~*b4Z7_LW!~!iw!sOpJ9er!(ldtxlDj#%usrE&KgW@b(X7kP1X@?C ztCt9-)Pxm1GFJDk_xvB4&r=m1>(#k3p(f0Bd_xG(q}u=R^bPEFaM99nPEKswYHZs! z8{2M@wy_%9wvEPiW7|n%G{!x7@BO~Nu%Es6nl&?Pmen>Ido37;@`2+hM8}wuj0hyC z(O&2&5qzDle#7Uj{c!|LG%V-|`uY6vr(8(GxW}W4r2t#EBK&Y_Gx0p2X%OP?90SG( zcgz6VFJ8o45@i!;B>6PE-waiXE&0M2D!g598ts>Wz)3qDQyfRCV4BM7yuM${l2!KX zyLq(!EXU%o#`?PX{RJ>giJYg~h`Me`B+Qi1NP1ghhMBOMBH${l^wOCms{Tr;svel$ zz~0bAS>>;|e^j(1_SPh5l9Jhg>`>4WQYx%nYR_lT2!m~~uyF|}JTQcnStC*4!oRM# zq|;J=w*lb=S{4675|m;aLPXEzD|oByUmjtGj0DnuVNCp8S6AEb$S`2R z(}5)%S5sUPlfAL*&jc*rok;mOQtg<}vD+%=prLtL&%w6fg2=vKoPdjIA7NyU`! zN5*Sd-UJy{V$l7`d8&)~YgQI(h1<6Lm3&&L>?iOYXD4Z2(Bt$;<^JEFKDH9|`T?IQ z@yz+PaFwsiK(DaHvs0&|=#QD^=-Cj#`gl@4i`>@pi^UtJzC!i!Fi~IBn_TUt$#kC% zeG`-O;(*nnxH2IM2i9)IGl(OeUw=-f>aSghq9z?E0tZ5LOp4D$1z&b=G`g=53pxn> ztl{|~Nx%WFco!^WDf}h!20}>n;trCZT-ub$3E@_|ae?qFyDOZ-INH*Nq#s4)E9&b% zO4sls8#=fWdbuPd3>Y(ce_H%+`6|q5&11Bd(j$dw6tfU~2Z^%Qm{+y(u#&W{wec(C zj2Id~=mbFmb!nmW{?27IZP@TLsTWxIija-A{zxvingU5uRU~FoSC}7tZj6V)TX(;U zy6^Dk0TB1QmMJR??!I3sJu5=Aw|C{Mv%YQ!Jc=s~xaE5sWS%ol=~OSI3jK$lL2UQF z;9VZ_B)Upqst6=@3yh>9htpf|Emh0NVY|CdX!pA64)V)m?^ng9V7cD9PVOpMBl!p2 z0g75qOINh6Eo6C~$g)&;DfvXM&Xjb@@yX|LY=bv4hAMf>nw4vp+x(?8O8N;*u2c^E z$;lQDCzUyh?;a_*g63RZt6% zX8g;*C!7ZpC=?CKFdv^}Q(BYCX~Ygu`0BWFS27KKc7-w?m-*y7&X)a4esl#rit%*g z{^0sxd?eH^ehQcdJep8JN%*lX9WDwa-3R4UtKnA52Pqz#Z&b0nB(jLo3T*^*Y^*l? zi8jMNKC3a%PocG^;FUxz+dn?IW{pgm{6#N%>h8x-bf=M)=u)uDD_cZaKy`H18+fmm z!$BRht0v?#^b@rR4%U}8?{y3|3@%RmeKqAaOv{sLGSDisYB&00z~fE=|Eqzm=s>tL zAShKh#B{rx}y1x zT|c)JUB2b+0KU{Kp}QY`@xIF)D>@*YE%r<4TWN1SU0Y z=4XmJwUZQ^A;3t~uiIsW6ums%oop@1Tewb=Rk65@KrCE$k<a#MSrqu7c8E~wqC?TIPY6k~|AlOj?#u)rEaK4aQ8Id6t{ydwDQ2o30FG5ma@_kf_Fv?5Dd>`RE z2KKjyw(#Q04WtaIzpz>v^(UPd)5z<`e(g>ZfB1w!i|ccqnLWAeJJvf+vg8?5RKTE( z>F2_jj-hodsZIT}1qX$5d*r-GfAuqI;p_F5?_x-f(0j(R?fOF4SoBAjkX=EocDzey zOj|?egebCX%=z%pUS*r8JcgP4w&$BjT8eJ-W#7%;W`BtxZW3CzC-NQ>_+V`y>JFp` zMy~0>6kHm;?f9nAVO=EPwo1Tj4-U^18UI_r^7rcctb~JkORwC7A4L4)$n#ZRKt}5x zvXM+J#y8W-Kf6KHD8s0a+~tT-iSf2Z6LO0Rq?V*KcA0!D*1IH%Ga zwwr!8KdpUaVgcr(3?n8($SJ;pKKRuF)1qT9yQyb!jM+gk1flCeDnkp?I=d5&iZC)x zY2OSb=3d+0Mi+HbFP>K=kFG2Yz50873`9M>+TtLCggRR;XG_`(8d73W4Bq-NV0YrVzno+}F8FwJk9?G>z zg}OW-Cp(;>$(L5b!6oo8>qWrKgyrMR57@d~+g!jmLV~onWAW&rOy_Tg2yh_i*r$m) z(ei>7jn)c3on|CDTVNneQ^qrawEP;b?23t3;29rZ8_Pf~EM$Aszn5m%wt-hT*U?+as#Kjc3_UEDld4f59H| z&5obMV)4pTQ(wZk4T6oImW{t|#Hf2|EIu)QMmBM~XT$yJdiKac}?!0Y=J zQ?bKzAhXw`cyE*Mn`@(4fKV)B;b296AyU3@5r zCQv&4oKgGsz~H}w2rkc~3;YQIc6DDBtpI$|_&zps`jUV~v-f=-3$~HS{u+XwFAUr} z_@iLd>Q=bq3fbB2Smxsq`bZf;i!BYPwS`7Eu+Tt=bq6cgiq-Yqfj{Bk?C!~D*P=)) zg)pvz8stS6Xt>{ayfCHBkm*f$Oi2UeCQaU9P%UI(!OUq;YLYS5q1uw>QhjHybpq_Z zzh*uoXxI~P;pl$$<%dNuqKPx#zO4mJV;8{S#jx7kXtyu5<(37W-4UTpxuT{4gahwlDX^7Q}x8b8c;TeCdB#}{`mb*!wr zWQ;1snlXU}&=&6r54$es#ynSUXAgN)RLoum_QabVe=-dQ#vDK9r}za0wR_A4VxF4q_PlinIa1ggB5-Ulh_v$L;|$wB+6!AJQcQj7-^RI|dVV)7=)ELNryUsd@x$)+oD`ZQM5a(mTF~ zFM+32fGx$VR3O%*1!$6LN-+L48PRP2RWQQ!x)|xXsoI9^$~(BnI`1k@Zv(5wcAStN zv;ouE6Ry`~41-SZ&)~+O>Sbvs*ufbqU-y_aBS4HdMNTV5rzsA#)XKwN-^Uu7;Q>0Ve+>=aw8-2OQWedLnbg z@g3_jzS^hQXI-Zivw<&;eK@uMpYfySm5OxTYog%QSpMa`dp7mHKE3Xwp$|+MF_Vq& zlGIG}`$gi0#(uB`gjC5eERjik@FqQriknz(bG*gJuedm>>or5Q5!^%5!o^KY2YdCM)Mcku>+QwxqeZlf6RxN~X04cvNoU(?m+&OYC2u5J3VR$+m((5nBY4edr#Iiy{glkPDM6Ex>+RgWKig zTTrI6(gtWJfN}w4ouvcj!>G`1%0d^cE(w;&*YgjHNT!NIjNurtuHQ=?R(P-JH&SMJ zx1o8T)s(H$zc$n<1e0JH7O_zl@;9s9!r8*%;Fww^*21$z7vqm(H9+;Y=4EY#=ftaB z)P&zvp6B=Zvu7l5BGso}I&SNks|+VB`$iJpaeaCyu@-L?q~c^lPeIv_ZAR8jGNNM z0vfFR5qhlasblSDFZ2fPhB*ZuAomrd^3q2pqk`5)Qo?b?5HjvxcvEQ|%t+9K*y?6z zwE+sg8dB#1u`6vVp?e@%8Hz=^7g}OoG@2|xKe`*Gug^<`*0Wh42CVRr*6hNbp>X14 zBX&HkQ_Q$W;FWf6&awHeeIDI$;`Q5hwi#S1yc${zNF#1b^G-aVm z*GlJARj>ru3{Pe^A&>)_sH3VcUxBUwR*vF4FKL}uE_j_8Rc)?Z@_EOGQx^N#;iF+T zOL>jT4vG4_My`2;uXHKaqOib|C`Y7X)Ou|~>7yBiJX)U(%lt8-hC&J&jb&C^Tbw?9(E>mijLCD?moTC3YZm$5IJr zJC&7M31J)4suuy!>^de&1lCd5)aALs1_$$+Yl`GQ*_XyU%aeruyt=!4lQ$b5_j&@! zGoTdEaHl_}o%*++i{6ng>5oAdrGhz8>i=qD>T@8g%R(dC>SxgzvNhVjW4}c)K^<`? z)5>I|(TAKWgP;j>XJ$4&$H~($UreRgS4QOFGDRszqsyQ!6IMx{GTq5h3xj!_1144py&ml{QS z^>|sTK?{0Y3I&yB#N9g9T!H$eq?M705$QVw3|HioG=+dzaOlYq?PDN4tlWmZJvF82 zjzA9Q<;y8gTsj0R#NUcSvWrS0b#sMGG`=1c-UEL}vb7$%Pnsyt3iQ(lyHNMLLm{eL z<(|l;^>1Za5Q(lWT{dqTHS2#RJvqyC3FqL=m78BlbMDjGCV!anOcnDcukw^jMVtTj5h^U`~pdu`!yPwT|Q)US$ckL036DEiIC#aM4OJsCF@#E zl@_}`d_ApViTa9mtB6rv51CFFr0J8rKa_L;B&vwy((&_*v=B*zC!oMDciP74x?*^% z{y6_TxjZ-Np!;DR#^Cgv${gCH(lE}51%lBu4*NvWuGWcjDWD>M*(09 z920I#dk*&iI5N46?pO9}2&wv;hv5AP7C$NGzhbpgxA1g+EDZCAD~Rtjuv}OkRQT}3 z&(UoMRfoT|Qss0Lvijcpd~6KQwTx>l6D`caG|i*GP6%# zDfz+g)%RcCO3yt-KXy@*uQ_iPbH}R0fS~LC8Ryk)dF$J#+d#v zb>h%;r%U2IF6peAn=o05Q=T3YfC&dWo;^c==MH0QgXGXiPB^OaMG zsfy+T{jxtLiKo5=Ghr^pnDa0xwDehAqy273gBV5kzlNd(CLq}9$5uDV_vxN9>)g%^ z`1X^;9dMn03JK#FluklVmlyM0#|s}R25M3`Q?!bzt~d-qy3vHJV4TcooJF9n;c(Mu zLZODNxfg!zFBrs55Znu?VLS1zb+ggtbIYbV>>sPQxg6$}uD0YRbS-~=^w!yk@w9q% zWu#n}fQ0k!FB2DH7ekDPXq(t%EZFcN;EDcC@EQX7$f?SR`Zoy?%D{4Pg{PI`e~w#W zr{nGBJfXf9s%KB}0!*Z4L*eI|o+he~-e{FG9YZ?Y4coNFi~*$v$hX@?qT!XO&!qHS(|LiHlQ-Mi}dN0r^Ad_tTfx#lNAs9RCBWPhj6 zknM3L^h>`>A`7B3#}{N}lvf9!UL|q7m~U&p27cIhFYbT&E;C0Z#b4EI{XtO7Rc_4+ zE%{mYU8O-y^q;&8RB@16Pz;m)K8&AMS*%49#~Y^*Gc_;S9tXa*F`Ekf-5A_WhG62= zD;n&?s?clUm$KDbVb~-;r_{7*jaLXc5!j?AU=-&mIGGYACq|*lJN#aX1~h>^OoY!R z35d@3lL67ko%DulScJIETi+)18)gjJMVyi@a400vGvf(Z#`-yBIC{G<$bgZf(!p1G zktDpA9)EXf=eA*wVh<}5Qy(Ux+TCa{WJ0fR!!I_2!3TQ?w-{4`04X~nDMMh-l;ya+i{99d%i zdfEMJn#ZafUlneI-T|vDi-xMK&?)q4UO>9K9}L%QU}bP3-__A{1@yDXJc4yW&mdpYIQ4Q!EQ{ zHVc)mZg1f3^$3_zrexZ(c|aOsE(pJ?zl!1k;rEf^$U^ox{1(lip@*dtHu7m`2B)D~ z7Lz5_#-!aIvw&vWcNzE7c6n?UeiZax)-q0^l~vfnL?g(FnjG_pq&IarSQfg$X~nIq zeL4#0N2^%%_z`gmSl2pK7m^)ZHi_C!eK0H60BZxsXl}%!?K3BRf5zro5e}0-7PIG{}iUc(%jrX%;3TBVNRHU zQ2@TL#KO{s#g&5>H%P+Q6LPYv6ujaW<lcXEfn zw@R3dc}yd1}#inJtXKnAa%e?%nWKkSPdyK5lxAwrEE&jV**1Kv8>l%75!^n zq8QE@h9e%2WNa?OF%M$<+zDEubR~_G;!N&p;)uVUTUa0C`85ERdMrFql!gW+CB!3} z-k+6(?d$esx;nKl6Jt1GGA0=&^*?mb@&=9oQOa1)G)laQ7Q#~_$(Jr)Yq`+Vz$IEr zYx9${B%c{s)O6++nszu}h+m(+%HV2{Jp%ig5NQdUJr};h&AbP5OS{NS%WyRbX%vmz zgGaF>VeM@!W$oj+pw4w_Q^#$?G4)o;eky$>qyAprx>C+As(sHRz1*m_oS39{1H-63 z4+4XIX(F)9)=CT;!bJba+iwVgdm6H2+Od1W^~zFHwXiU=n+HQ0!zE}g2{Y5-UwmLO zk*hvGEs(O^xV}29x&X7FinmRLp=e+@>KQKS?55f)p3ehA3!AC~+Z(yMegykb`rZ%h zONacZ?1C)y7w#!(d@*FV0#nT_$`vcvG>RpeCa6nw?@vDkZ zGn=)vE6|p!h=T~9x`AR_jgs-5L~|cq<|2X1a+=YdrhdQl zUY>S_x4W>3Zt!qgZ0U{5Bp#fpxe(^)nAmX!S<_mlBVe1-e2iEwt3M;X_@C)y!ts+z z@4oyRD`;ipf~fv_UCllCh{w269k_M#4Y1}-ozsXH?DH4=*73ur+Bfa{b&cj}&I)Jy z4&}0Bm@*<8pF+X9|Md1VfSeQ|q=&i`vUx!bj0DvVopZ<=XlK&>ie!@4rb&X+w=<8F z$ZKe^`e4Y>)g}vH`4dn9$ta=)iWal4FhD)udQWeAaL|PZmqpbrKEB!FBd)QHX>mir zayY-Lz1nuYw}o_A<8AoSc7Boj58H3<;bGVXmp0S6{&8?ynORaw`Kz`T5xWKjAL43wgge$RMWxSs!GJ*TPURCxyst{L4ikrR(|Se*VYH zkW%`AUV~^;7m{s~1B1ACX9y=2UFz#=*5OHb;9ek4?%t$AgdrRH*zbd;#BRk0EpMN$ zW-`gM`95f5COt2p3Cc6eTxNibLNak`fBQ|*CIYZ~=HNUUWp>T8AYXP$Ky0(X$ zy}cmvOV@PGI~ePe^|6~UdV5iU!3&RB(m_$VohE~!uUf)RK<8N0R<>PmE^VDYw{MIo zidgqpiN_C^0zV!#>-bQ^WEmWf$)fJj=;Jlv|C(wZzb9%(jvz?Xk?7DECeW^A-;D&r zakWs;RdKZiCcK0J+nfoDTPZz$ai?{o{mCJLS=1mBNMApp@noMm52#ozwI7JdyE%+HSE zNc97IK}Lc+XsQs-5H%l%5u5e z{@Q3;;=hS}d9s~Xw<33-6<667v!aUO?p1mqyX}i&N&kb84o_~8=r4IbtGEOmh|>&^ z6@}j=R^BGA$Agff^a_iWB_)ea)LjMwN$ZY=%*b*s3C#^@Q^aVSmLVW%};MTz$?5>^JHFG99@P$hcA&m*IHf%7WNVfIPgDO}!_G6jci zhcsew+laKUYQ>2YdCK|2uROG1;2!zWB)X1uHsl*N^_uyKv5%|^u)a) z&wTsst&?J~D4|C-liIjLNF^9E2?Yyh6F0(xMBf{EK z5?TOBE_h>^;r{K%gx$=_9ObRNf2{{PL&7&ENM{P}gmz}F2bFnR*;TZfh}|Sk@5L3h zIsrKc7xU!^3)Ah>FX&8cEQI)@5d~1NK=`Gb=M+G@Yw{k|Z)qonu0g5DRA_U#Zmlj~gb!agdVX!7 z7No7vo$t0q$PH<0EJY@)Yf0UU`P+zb;8e;}iN&E@7Cw7!hfPgIuS3S5hJCpYK}zM1Z1li!b`2L&(Lp)}y%!qyj( z4E@Y~9I^o87bU#&u}ZzVo5&jw9~i^>*O3HoM6x%2A~#kJFHV-s+lFS93qTWw zk`=pNW#f9+BR{50Kx(`lCwg&>>e;CM`!^(~fQZ$zhVaFHVr;`-sd0Q?4K3W3_|e1g zzx%{9X7cS;PZ8sGP$M(jGA@Q+jw7fZ>=JzzSL36Wj!cEswlyw(4cHZqC|+1f=@qxh zGuv_ir+MLWrzRM!AM;6Dk(PjD{sy2GEGo^brPwKya%&B0mZ#gXv+N9NIR80ROE^%# zb~3vJL|SwGPi#ouT(dQMR8BSY?k>Ma=`?e^$vm|=?f#P~ zWZ`q9t(+Dv4qMneBuY{ZGMKMza$$x}ggXX@X37<)#MR&RD~Fc~(S~C&lkA+U4xEz>$R-uI0ecu&{uHR}z>0!z3w$hWZc( z7lLjXFRa(NuzXAPlcc_2h%qWcZ_NO?)Qs7J@@w<}fVNzS^#QwTvWk1P<&D_FD;F9c z;9N&2fb~^#?y30Zd0*g`vT9o&blP5A@uV7C!!cE|Sa|>Str?%jVMkAf5qx*V8g zgPgF@c}azVs{FSJm51#myAN}VwQ+iHiye0FgPe&z28C=#FW%U)&F9>qXgMBIjVS?T!R$4*@rp}sr!esMzd z`Wx;l94KCk2Th$;_LooP3)p`4&apP>MW|Y3O46$v-maji;9#NIZd^86*l~7~FptQO zcc3#5EuQ>x8fwDNRq>-L9kX9chp45J-pn=nd`$QS;Y8p5jBC-H99dnjWnZ?>Nu4Ql zn_wxhl-|rANUer1eYBJz=lqdwW1BNZ8Tzk?s(ltwB}aV}KC4_JkmA2tH!n6bXGa+I z8z=GoChvXdCUw+SNyw_}R;Fc7a}6krvvr$tI8uGQ@Y7n;E=zx&N5VfVNbBONjMnHU zWMml|heSiQ=o_Q|#otI=NLC}ZK~rIUHZ5jolOPCm3pH6I-ZP0H@Y+6I0ILEA_=>~# z@zmS`I?_mMY5AJclOC(|00>ah5HeOXWWg1KL?muY>X*a`?N(lQ6HY|pX1Qfm~Tlz%UG&9CsByjr)PDzcCG zr@DyoG27pnks78AOBDIZcR@`nE%M(GVp{u?@Yc9prvr|T(dfu%kyWXjqJ@)bDUmYP zoi8{Us$$lEOMe%CLou$xrg1&#U}fnsPGeiu)4ZBX`t}U&&2HE6qd6D{H%#c^i#DKu z>vdASL^G)vD1Sk&9Tu4gcx>cKoy)c5T#=I8F<9;*Gqg z<&+{Bu2d(wHw{sDQ+xw#8LeWMxFKrP&O&`Ph+${1@JkruSE3{Sja;kA(h&yC*VCie66)_TN#3jrNJ6#;6044j{$rXdTEJcz>zBufsvIhtci|;yaEF z5<Fv!J4rdS~;LB0URsXESo4EC4@lnO}xmn0x(0XCOOsIWL z<_~g=U5ho(Af@M8n$u1yo*@RIvz7czBkLB;|<3sq<=$q9K2v!ZjL|KG-?#%D|Zw#Pimmor9WU(@qm=E3Q0) zUq^UTpTo)#XbUl>kGW7Bj0L^#Quc-ka2Tt`)?DlK2vGg(&COIGM4@a~gj82&4%TWe z+)h_ro#;0}dxqS`)@w(50~4hI&`KT4keDa6h>z60{;%8s@J(p=ohV7pMj2jUe1oE- z>P|Qz-Re;)j+idKkYBreE;;nkH)$B=;@R+z;)zmmb99nF-}<;ZXv$j*B#-PalUU* z^jnYU3%6CS2HrLvtSv*exSk5u1cV$HR-Ymubd=8_=Q=9bQjvu~4%F31_Dbp$-Pug5 z5vxE2w*8wlXRcfYYaG9Dfx-~?!f%b~`cQ%^RI??;p%d^Udo_ZV>7&JfJ1&q4jUAhU zWbEm#I1#Z?N^*HH5Z+Fn)yRq$-6+HdxbndYSFYWn%u!kk*>}6mIvAc;>oC=#Aa{x5 zQUV70iQ&Q2QdBbYvCmB;FoFh^!r9>uO%x_*o7D-uy5jiBl5iO?6X_h=H0ncFPn#$El^fE$ezS z92yt^37uV(E5CzQl$7Wvjj)Vk1xkp-fmSlNGgH&~l?xnt=LLQPK$I*vaB0AS&(Myf^3MOq<8F_D7Tb;BoB z^nb3`BQVYh;shg{8@S7rX+b5M8c?XAn>$@VWMSzH;B|%QvBqHHjdsY3p;;A}5F^(k zU^ZS1Oq}6+h{^p$FwhuQC#@-hJR6$B!sXzR!cc%ugPMW|d4LB6gdvp2!#*J7>jR`F8!5q2NxMV2qrG@U0B+|%B&)vJTyMUjR9#jnIKZB7ze zD{i@W93D^T;ao$n{}(}n@-+-U3G&+*f_Z;#G}ged;mr_9ryF<>-Lez0Z5?*-$fFnOQ}Ftl=vyP_jcV{X6vw+n}c zZMu`@c>-@Sz2u6=E^G+lB4>P6HQTYyECU|<}F z0!)!G-WLwz>_dKd+-&=jC1K}5J6_NeJHrx%{W$N=K&%R5eSYgUPMpE+s<74)Ja@b- zmO;b$RM;kDKCuq9qZ|s|=Ww1dc5qcI@58o17^_Wl=a9aO0sUdl4$lq~P#>xRCzjOE zDMXxm5<^hor_1v3=9~Xbc4s(Fu_iaAAEUzH%I4mhM0!q#3T`RG-mb0K4pcj5%dRYk!7wNFZ*HmnkC z_D)j@Y}n?osL5(9K!h|!u8u(BUWA{ptu}0hMe`vKjo%2|o=HOAT+NS1IS7x7odfDq zaBXv^rNC|(h7~{-9V^cq=v%w%>!KEjmht-=@#IMaIu=dvW~$pnV04)(=ilUNnx)1X zCc^qE2;93jv~IDZq8KJdAYc=M1UThxPg+w>WX%Z31)$X^nLxWTL26{5k$8qf3+u!GHo5X^|Wsr&z4PYZkd3!3a=_ z5+`IJDUmc8vF_e6H?4(m0HvFBv4}A(EVwjWDFk$;BKib7#_1o)mS%;?q!Svx{j+e0 zT-qD?!l+6H5uhl9N)EDEY#NG@4P#&C&GhuJX2jUgu@UKm8!Di!u~J=EjSOSnkPwI# z>`FipNL#v0ihg{g6UQSt238;2Cqkx>CNsS&BM%2bH^TwE1c~uRlh6J|Mex)tlQ$DeOhx)u3eB1>EY<>h? z+n)d%8e;-OJ}E6IEe*Lv>jpXz2~(R^NQ-d?Z27f?BQ|sRV}O*-w(zzu zPh-5ty&q=31_tgaL`y4xe$=d&GjiCC@#Zx1jpuNbt0aR}NM!XO(xjqpVX9e)o}dGW zUIat09^+)YhT?68{BW#tvEbI4s>mT`WF?%dV7r6FBa^`d3Q^%Ol1$7jZ*F6M$0s;iR#&zX3Rq43IlO=H?oO4| z2}^nPDgx+r5XU#?zrbBNl0l`K1Hk9CQ|vQKvpJ5fFCOQoVJCRl2XN^@?|eAmtXOds z?OGHZgWo$=au76Xfxo5G{DsbK0M!UhFrQ|On335I!k7@NKi4~`PZUs*Ye#a&%oK%A z?yMt?;Hc^qOEy508%+TIaTXV#qyR4eSWgtYVi`6ETGLsag(cacx=sUC^#8H|zSh@W zog()tTA_wC!V(qQgsYJhWoM#?kW%{1=CYaz6ffV(OR2QCDhTv={uz{s#Rn&j81TZ_ zmQ<#BM07iJP4}PEVg3Gj8h?PRan%*Ad-Ne8^d;Ml;^`|v5Ub!#oFZ8Xh zv@~ZI*)~onR?7HSo0Mv61!Y_f30DpTO`DE=O}BF#oys86*9VT?VQtn@R$ z5;ImcFa?NP^$k|?*OEK!#4l8kRi0>(KmC0^5W_4CogCbB`Tbb=w?7JV%++NNjp6!y ziHMb76tnWsp$F1x0LVBTloNMP!2!*MMP@*1ObU)O4rMHTEix{i+xtb_sIPDTO6g0r zuT#oHdNqG3(f!~ipuUMQ zRdp+gMJsv6+%b=3LNfld!`coZ_Vh+OD+Lx_ zJ(W0C8k@hw5gT5Rj6%*mYTLdaqN{^hW# z=rnSsmO6?iAn$6wz2ERX_Q6Or0rTgva<+ite(&~Hx_6ax7G6r3eA&t#x&sJ`BWfa4JMJN+<(Qm7$@B!n{@qa7M%PAapFuspXyzh^U5Q6}DwdSp4eOImzD zp$>`7F3=LGe?r^mLJX(VU#lWv7vzu#(@Ed*%Jp*onO;3jBQ+Fi;QQ(%%ZL?UA25A) z)QrGpeX{^NUP2HGZJl1nEFtR)GELsY7tBnmrN*(}SL}L`X#NRKL$R=PcSy8`OT#_q=-AFRrzd}g z$$`SbjLeP#zQf-t;~cI6=_(9q>WMRFfKuRQ6*?H9=L$F1dDk|B90>&mX)E$;!zabZ zO${%{b#@_*k8B0c2pf(*oiP&b&;Gx1*9y)w9e+DQeyp%|hCEBoOpDv_Epkv|8jD4I z95lz4c5uydfD7CRK2%cal%zDDFG*K`-}0IFmCC+1qAF`mQjaQc%1!GdE5~nDY>Yg+aP=DoHhW)HHN^09=6?4E-l~CSVJ1Q>{w?WU2|p+g-G#a3DHoqM3W2k-CG+FuVakCa6w_mj2 zR+?MQqt06r%2OEBnpo-|T1KiYh+8= zu+k(U@PY#sE6Xz4be5Y!Y~=`SZktP@sI{ddX#vNPsu_Ne5H(4CGm%YsjDr%><(;9F z4C`l>MTSP79TeFwOTrU3C7C-aS!}$^+!f`gP=*>~+~i+m)~IDjC0Igv$CgUXeZ+=1 z78)BGB7RHs2X_h9k|x=4$_kH~3i2ojN6CHkJzggwdGQbjT&5@(fRSHQAL?3mB}%zpGbnyF&*q+~hmeav0YZLe5J^b8kt ztw9%C0@3T}AMJhkt_q|IB;j;VS4lDRN$+{JPuZz?OevyPkrlRPnbO{~s zy&!+%{ehFmD-`bDtKarXUQt%vlRr8mue9!&&rc5$#0o~mn5dbEdnMi6PV!8) zQ0rWOfP3Exe23mX^e^odX?k%)^J$Q5dfHRo3Bw9eYY2ai*e+t^Wp~m2C@Tcb^_>U5 zZg#wk!}^}i+m0f6i1v;Kok#ga@b61Eid(7v>^e_6;Vb`eW~o4`4gh{ zqr}6iWlD@Y+X=^MUG^zBbnM}WAkX>Dejjj+t=jHXiGn)wQZsvzg?;%M-exAuuO~Jg z;zb^**N%~)x4D5z%GWBiwE)U3^w-|X(eLao-QzI+5*h}kT)x0`%PeXsk=C(oNq`&F zjsG1ERv6BH)!VC_8T&60+I4bh7Em=XW6+gh&lw8bnFm{;!a4{?<>lm%xSsv-KQvth zR~%i_#1>gx1B<&YL4xbz7J|FG1P#I6-JReLfuKQxySuw&wI{y<{$LTRM)Mp zt}8E-zAAL$8i$CgqSa?Jred_AEp#n*ixGSo`MC)CCaO>C@IEMo(*`a)RzAQw1Jizi zkqgg-;=S)E-A0_wvs~?85a>2D=_3f@m;E>&gc9*}GK7sYUcva-cRcN`E_j*=E>jytkEg~L`BdQv4GU=VsH@-7Tgg^{I z*SkB$=elX$yF1p1JX0!h^M+Zg^N>0ChEE=15p^|J6tvJlJf4y=%0fYDAj!UBfZ^mNJyr_9Nd8gwx;(1U+X9|w9T2?fH0 z9WmW|@R;=e&>>hf1dy^V6yitFaL_=;Anif#N?YEP4~@g4-iYQUIA6J#&|%r^k$Xe& z0o%>ybOde7akSt`sE!fl`U^`2$pEYOgE5^a&lJfv|6;@>|B;rC71DyD2M(j0=~RO} z0G%U~z#&N~KYq~wDj^YmpNTv`?k(dxtH40t6Mt}A2>tA}d_1yb_x7@*x?lAJhbW_| z{d86NdF;JcQM2XY{U6!^_nAUP@Bb=Vu07#?#$|HFW9iMrWB1)>n3vtB9I0ZMY!AbrF9}k1C8%v|t^M>22z-h`N=e@^N%hpy(lMa0C}$Wf zjYIHYkapHkgX>a`aUjI+m}X(7$ar;+^72Mfql^s+fKmHS^iew({N~=n=G-}BVeWK^ zb>1J;GHCF{00f5+`w`j;K!C&IVEqwvV3s+eOhA@H9b->xx8QIEBZV-_K%t0w1xcY{ z4tXes0o`jYEJxBaWx}!E^xo00x(#mDKDD*EBGP#kRpw~1|B(Mi6doIEBCHi}k&uh+ z182?2VMAob9_6hrxbx|6-yOn10dCUd4?apn$|<%91n|0dZ!#(BcxckO8exTSF+!x4 zUrd9sMOJtKJo{s16Lysax(kPGJnw~#aRL)jHJRe{tPw*ly7(%!t z(`6>(y;<52#<6ni_$!l_%)7afnMVss;FctAXiDhM<$;GE&lQbV`F!?wTZbS+dqW?X z85wxNxl7qvV>4R}N2aNPWb1jDxF)YY-QZ zc=l`hTieMoWpbfNDT;T!(pL3p zvY&O^KcnY6I&JGXeZWc9Fr5Nmz93V|bYPso)M61W@!===zUeFGrayz^zkWZVUDx8Ym1rH2H44-L`fB@9Agt+sIx?V_NH9E zGS32hin(BtZL^Ba4P5jOlakQZNb(z6>yR$YFILdbqpv;o**CjssMz#>yHnGCO z?*KQ)<~emR3tvy`uOZ#A73nzyW@K=KEEB1WL4bw24xjEZt_4mT0#BwHbPQX5@&I`b zLQ|T~t=Y8T9Zx7F=8DLj>nzXYtIV-dWqBweUi*u*p7@1V@Bxj6-e9WsR?tqxF^ld$ zbhWpJqHBwb$c{|`B0(ME{RQ~n5$Z5w8hvRa=d*`1lf3V-Tf<$nxg4k~J?TR;s-7ix z##ULSsWHV4p{rnEY+24=mNNQ|iKtHH65^VQa9u>I!3Lf8O3m0uTquwQsr+nT8!kL!Vis&t%Q?2HuPX#PhPpkyA>b>rpjNaNtroxYt2(f$-a^%=K%H*osl9 z92V$eJlwm^u0b?Yq7bVoZYc1!RCn}4*4_eXQV)Z;URY?7pV!2h@K#$4gOZX(xYQea zStRAh=_pt5cRD>yzLcD4M}A{k<}G5OL|odV7=?dWGM?T???+WCuM#;G4}C?3iu^w2 zKvVEPS~X9XEr+Mt>NLZ(tkzdIJxn!YFZqj|J)XCMcGZF90>lEuSXXojh63G^5HjVE#17Yb|mK| zZY&x1^I-BZ-!gij0?pdDejn_bhN;4#yM*e3xXwPh@iQVILD7CBJY^3;JyE+&1dBSU z&*tlZxK<=E(32zne&)K(FrQ(N6B!*c2bQVT^VxB{4x%5WCr`_&CqSJsbMF(XW%e*h zBPM0Jk4^QG62#*yqXS}(?I&mhT+AtrfkgcaPqP~fNq6PqjroCCb_{+}4joj#6mJ|M z^bW}tndE&<#ha9wy=?gx2R~)3`Lbr-p^M;_Z}WCOL+vLl_Ulh)27TM`#hvc00v0ak z?M1J|53TJ07NL9)C8!QsLny=An@pD_UdFk_{5+ro4Voq zK-&j?6%5P~15PQT?40WWKdpE;z|}cCLSkm%DzY2WpV5+J81pMJwEE9^nnKTkdGL23 zfox@Qd91;?qDxw$6BhY&g&}atD2qtHUNAeESJ<$Ey3|f}x_uED6>`L#scDWF;yI9= zQ{{~qbeb7{?XYYLZ)8`G+4y4 zneC4hNHLtiVMMcE{KxW`$f~IB#FMWdyCzmAsNV?b!bdjg%4DoHm1qI&G}j57M(2j)1sgM5%V`q z)wJ-gFP%t-jw*J{{9-||kf27f; z(C0et+$9@CJWGUiQ_R+U%KYk3CsB4P^fM*byCy7-woJUGULFvJG9A_O7~ z(nN3WLJaO7JIDDlBR?SdR1m~F@RV6&0TlVZ426p*H z*Iq@OT&ct@Db#Phr#)q+feRFv2Vh&l@Zz6Fl+cQX%7Q7;i`~b%QbB?RH%3T$WomfO zN`(HOrs&ix`m#yA5W>))u^9bwIml}8?=R$Df)zhyIO=jC?ds9oYBC^ucFF8pO%+NS z#?nB4k>vy){phNyvso{!jeG6g;QzRrbS)wkgMBCK{q5$tOynjK$e@1-$+ z4b5vL|HAH61<0L03l_F0DC2^rN^d{~@1{`=Kie*O13K9ffNjRK{2AihqF zxmi*h5&uxiUp{G+u4xxv5>2le*E_De_I|>`>Gu9ZtL^N2o+g}G$?Nk6eyq$;tgGvg zENdF8)>#97%ATgKDfs%YqM~yjQZm2>I3yHZxmb0 zDQj~Pknswo?coP_D4CI`9z_SCU!7*(m2eeRhJfrxv&+1$^OicSfV&Y4h?RHPYGe0Bjx zMVN0#(uRuKQP`IcGx;Jdi#}zqGY7Fg+W8e3Ql^d45S^5Vtt*kkYvHfv&zP`Pe+2Lq zbZNZ^Z|zM)g&Q>gSb$8p{v#Z3Hc-Ox{&qd_mDO`R+{xwPchz? z%AfU`HVqVMc$g0p-TZ7c283*o`t4_xQmIDTR72C6e55{;hCw*6{ar-$(0q(*t@S^< zNKM(b{aiTs)C{1)Oh=1AsAUAW2JUbU38;iyO<{8<0uiYD^BBXlep0oZ1mo3(%ErW) znb8p87GS=Ntrs$WMcQb^^X7tMn=K#2O#5=8yfg_*BowsMWgF=1l7XmTz>9@<_z8C< zm@y0f&Lds3n8YnEb>f@#R3=sn9f} zHktXXY~@D$`7<1MrjC8hvxpH0xznrsk3fUbpd_T3?cB62vMj(OFW~wAdo1 z67#$6OPcQ6#^HKBCY{3z;r7dl$cxwy>|CK5f--R5Q}6=yoghIGh4>|&xe_FHgtve)4cyuR3ffch>t&N8jEA03``|p$Jkv&_E#MYs>J0sF=>0^Z zdfp|XfRw9<1M_!TO7y&@NxaBUyoZbu#41yRj37F`LkeFmtH*_0g{fN|&$HTi8JK=%jM&sX6 zlxUJxAN#dlQ6OJ%;KERz{wl0B9kDP|YgvE`VtSw0n#p<0-{HJ(7K$@*2pNo7b3SQ} zB!teA>a4qtW5-q=@(j)>D z4t=bmp!jSXmAOj;ogJvbH=_Ks?{5hBF}}kSS5q)`%gZ$D@Vg$*E097=d;Z^pcZ={58x(TPgiU&kqht%Fha8r zXh0Ifl(B|Z7m;y13=702k%yv$8;)#Ev?p3aSO-LU*1I=0sOq(J(qfG|!h6eR>J-hc z0b^619(qK93n`oo1<6!1MZ0uCm;<9>>BVSVk#V{GL6jE9jbe6Fpgl@NXv-6WAHj~q znS>zso>3Qbt%HzsXIaSZrk#pxgNrsW(`NY3AYkFyKn*w_jo=f(nV;SVKf_WK+b522 zD?Z-)9jy9e&zBHvR>1#MneEDn_^fz>m*f?sf=ZU@ii406y)lbhv1)W;ZmM0Cbm1#W zw$|u}-zV;Sn$zg5aJ=Ag_Se^p>8$gB*YrO+7RH4IYaHeP$r83PTHx#wxnK5KaKB0a z9FLa5|J1JdXC_>iyO73r#dz7i#{SWjvwvb>;fC#Ew;_56-qP^t{J--Fe+jff3Y0waI?Z(n&UP^?{+SlH zA0GBy=F)|A{ldkvtEYF^sC5kYL-&C9XWY0c7saP(1vpI#aVw#~Shz6;|Bq{^j9s55 zX6ymCA>;JL!bhX@4p`lU6z1_^Q>L7I?9Av4vGutfve#q8Ysl7Sj;5s8Z*it}a@v?! z*dM1=6evh2igTI65-j^El@@+z#d~hBb{@xvJWI%3jyZ=8mrw(622FWwVnd25wKg!F z=&2|5sS6!QF2yzWq2NGA4a6~pQ6%lo!XIHL-Q4Ljg42<)*+==b+Z)CKUQ)EeYDTVZ z-dK&odAqgl7GsbT#OHDW$Ss$Si(Ctj2gRy3(6YZLTn<*C+^SQ=hlyut)}!xi7v8BC z4&c?ylE)+gSNgj7luCVSBUG(}iORmk!V}ZuS7y~%&%R|pQM*lJu)vSYKdCYey?7~i zS_B51J!M>Dal-_wW>NwFll8$`|3R;jgI!xqp#gk-Q%d<}Ip^%oTI6ivr|K^nxr-UP zy`b9u$YOPnfA~vs6RJ-y7o3GVrr6GKz$IzH8=6n|H8w`Fsu5p!Gv~)6E}cMZ|9G!B zdmKOajbfYpLj09ufIk9y;0{A5qIG}_O~OCg95K$>oXicTK|s1b@8r5G`>D(=J^dZ`Y||Ecpm4905W)f0INmGZwam?EdrG85NtJysG|O$C<>m;Ak@ z*(B6=pF!wJ`%u;X$Y0mzxzg}(nk@h-j?0M?ASF%&?ZDXfeE@6$0x_bc7rK!y)Q5;J zmwsO;=2IAfo3VF7!b=Ssz0c%(+_{1c9H|kaLh}lx#5e$}TQ!8C9NdX+j&#?s{4+Q> z%bys}{I!-k<)B8sig>Gy%XzB|8eEG86eirU8%BmBmF9OWzWq_)Emf4#@9OdGQK)|R z7pi>nC9P8fAtyl#O3K-lx2Cw`p8%{%WrUr9m!*&oyQ*98K00C*`vKlpzrP(IBoMq1 zFeZ-22hO<@Ps8lZb-lY*>cCjQGyt#V&3Rc&S8Kur=zc*j; z6&4y5El)p_hyKcJKr9?T)uBx>1cBeZu_HE|6&c)1qP4=33=Ln-(%t5F=d;P*pMN zT{dK^01*YoddjmQ=tl|=w(CKMgiFzl|nC2i;2{OeVBWfF7+*3_>Y;+Z! znkjG*TExZIHROQgEHN^I+JUMB-2-DXzZCP0)|=uhBcpe3K|d_MA9% zn31xA9qSrk8^tXS?_9|0+G8gn5b?@_W(LiP|0({&l!XXxw5EpA%Uyf5v5LDi7JGpqYSJ||F$HyK_ zZ@BfP#c1J>A4KPW?ll=^?vB!nh>WmqKAk4Yach)^Vay=GM$C()s|2$>V`@H-L3@s- zB6fs*OS|L>2j~t6hvljshLRHQT()@11ff}2>;$Cid78S?^-lqeMGeHkGzr#ZY7Ua)w2VI#wLKrRyKQr0ZoiKZYLLX@kKDRDvtKWV6@cV5_L&&*&IGn|yXv*XJ~ zGo?%zjmePK)9RQxm1*20$4p&L1p7jbMz2KxI)%5VSAU3)>rBQwPu@- z2r53wkFbS^C>7hoTlY0cj+8!%u+Y`p?lHD~#m@WMQMY1nf9~k5&0=`=@p523Y0M$A zs*DF8I)zSTM#icLzE}HoO~0B`r8&X#w%TU4`&RqE!_N7Cv#S-$uuB?M&Wi@sz_8RnxV$?|KWYXUULt?0vo1kk zS+qEOn1F$j*X7^dspQ0vWGIPgKsoVRyu-<3Z>U)C8WIB^LDXi4}`(AU`jqw(d^`4n-eoX0Ns2h zcjjk+ooD`t44rC#dxuv#J6h%R>^2Q6Bk2rt%6QfS9KSBkMci^Nml@uCE!Ss$r^Abx zBKc^z|8x1DAR#(TtqTiRNK7>3r> zTo(1KC_xZS?oq0c7Q{m5@Y+Pa8;-08>_EQvCBkAQwmU9=dwPRq46u`;uM?XB4Wsdm zi3w2OhJO~vnvU~sV~Q5s6=ws@(e%XNL-#JR^JJ*JN`?rMEU&VMFmgkk+CKJC^q8K&!1LaqVV{4pDoW_eQ%nae;prD-T!y8v66$%47rO- z81T5*HaXc)-{r{H4kD@TuU3wK7I^t%6%L==l#2AAd6{s4J_ zKt`;GYmtT_tP>@yM_RWmivuEKjWzDZ7o>zr+~-Ne)1<@bA?d*HYNG^`9pvE=2eVr@ zN!)WTlqR#uSijQ14Z#D(NASMQAKhl_!)wE_!|dbTmp3a3l|H!~z#uWX(x)Pw)@R0@r& z&ZuyB5FZg=;^7AEsUa$Sc?KA$9#6|H?~%T*pDk}M^f44xO)+7cbm>&{Yd!+W1t~}% z6H_0^d?4T@u}c1c@CH+4V1xMM{p3hM{6~cE0Wb)sqG&j9cpV91qZ3spQ7?uHeIG!4 zUxUeNWtdqg30B<}byL%hj7ssMXy|oc=!)HU$L6S#+46%V`LHxN zaDfw~hHML8y5ba7>72alS{b5LcSaaK;vO35f2epGmOb*ijFDxq$?3c_3&Wq ziRK$oZ8(u~N{iZx&SUdP24?=cX!O{oVP}}9xMf228r{Kj=tcM8kiEmU8greS{SK#{ zqUZzcd<4pT5?51Hu4g4EYpJtUa4C8pwlqvJ@gI2z0}#w7JPQ8kmQqTRj%Lh0QqB}=SLMatNc`(h-0FkjRjb!R@m$PXUD^k{uk@IcnZMAo)% zej!!W%HsV`j5_%5MI7))Q$zhXKIlu0mA!w#BJV-hal$EW&u7ES7e`$xjubRs#4peS zTbj(KDGI<>^NH*N9LPqPtx7QXRxxaBY4@o8(}qFc+m^E2ixM>~oUcTeu_a5MdqUFTHJ$k!LkrI?R2-B}pA{f)ATx zasQHJP`Kka?Z*!|gI?*D`4asrus4DQ%xlyY+E(MO?IG{2A z9~ZkX%kI$F-0#XnUlM)Alnj4G602@$YKKV&xNad8M2(|xD14I!wrmFqxW>fHzCFxf zzAc@tCAVFbn6;DwS6c!*0yHcKQJNaF)36UC|N9vfK|`DFyD>M`?M_ut)w>EY_B6Yv zI1cTPASD+5RDt<^3Vn)epjP4QjG#4N!|eW_wXO(L1Viu2*D)Ub&Fj6s#TaXcQPC&o z_uQ9_O`1{z8Nr9f&ssdgD3;CQNNfMxhMi(rE>TM7WXEz5Kf;=zA3~aWFVFThTgK!5 z__e9aU~WlMmW};MGS89~etx-7Hvjv{1le$n(dIm@+J#kc_w9-M*!a6zzWI5x!r5R| z;x~78T}J;Tqu zH8QC-XW!pfMHVFrsn4M%Z=w$^Rf;{p5jk8==g(w#^g9@PpeX~F7($2>`OT2M$r-^Y#M^gQ)MQMFk#&?lOb$jYaAD5?H2!YJ;8DyFH<-Y|{i`J{ zf@fDIK#R#Fclh%bGYetQ6g=GTBB>t(6SAQQ{&5fEZcpmw4=ed&u(#|T+sDH$)Mv4Chg&-h5ZNqzttR(hYBoBRTf&56l4!C8xIgr* zqC%r3pWIJzp_axe1E@c)ru{j#UJ`xG5FKoAxMaB%&T(cUF#Nrh?@YO56&tC?6l9lE zBCwJCBI?%m^02PEdH8moB*yBfx`nGW?hS@vsUf1p`u=z^9Uj2IfO^1&;FAEqtuN-* z20suecqJqIb3YsoF;kY-M9c6E<(?PF-Il`INvgvQfA6zNRKkK^0+~Z>0fWAhUDC%6~EHdat z0pnwE1n&@0(cB2K5e!1aDXu;l0gQk=)`{yc;3@M(S>o>!{!Y#8T`lsPWl~chXe8qx z1!2gyA*G|iz3G$|Y{XS%ojls^_^o#4YT0Fx;D8c@3S;k7?72}&EId6M00}Y(4PmbM zed6lRUsr>tmnLc)669_NITD9Uhec#cNIop>7K`LI%$ZsZ1ub$+w218I$*-&7#hL!k z^7qd&Y`1s8`MQbE1i*e#nrDVWwBoLO{n(=W#4vZgRRxL+gmgJh&?Vi|(WmR0WE;1A z5)?EP`Ca*zBHlu>Xq1?8pi(bR(jQ80KMgGfOYbW`6@h;Wfgq zB=0M!(RfJzu{5o+|LUK=vFxrd-Hy1V(%`B&jT2Khc&fG4k@|KdEN(~m+I&+T4DtW$ zPoNZ|{b|B+uh9i*wAL1eYziY7(H-8W`_2g;!iphs_DP)ZWEYQw!sxW4H6;@cRRsYq zAITRLYvPaTDq3>mM;lET3;)4WooeuRo@ESi@Jj#M;)5>CPB!!gDk zg8J%|2zs*n#@}^PzccO)cDhfLSviUyV2zkrRk9Sjxyg4zu4-QK=xCf?H%v|#!e9A( zmIB4_#mJcC`*M_Rh51mYk!WRDce?kGiQ!+G3|J|J+JL#jf#a5MzHn#B>0-f@9>~@Y z);Qf^#auRc_$U>(*ISC?Jsjb#pO{wFZYYarL#)Xb-QOnZi`dKt7K6gRdupN@5{P|$ zUO-kyH)_i#7o%1={YqqLTk@S&oIPqL-A+$`;pMG zwrz7G{LPP8L4w?aQ_}{)adwlY|3-?1|M6oo^(Fy>)3ybOiz=5QD>dKUc!=ueT5Z3f zcT7R_$FHr@QwSf>!~q-#zH2^VCN6>1a9bI9i)(!5f|M78u64dMQ@cHuHK_>xcr`?T zON;*3e`UFT5mQ?eA5@H`nvZ+S*=lVFgT(+I+r5;0=%8_{-AfGUE@*rrzcUeRIGg_` znmS9@E*eoeMvLD9wJatzr|tWgYe^!h3G~C85db;w516Rv-?x!?L&a_x84wPo!i!3RYSgkZbPIfrRc5^%P@$Qi!+s^O@_6Azzee@(=4Vt z$$UuAj6B7@Ig{bnyn-^xnE z#k23xboS{9Flo@=mu<k0te?AQGUn$I+c50wY4zVR)>rK)#ug>WNsVn}UU@&o`<0#*5Yqqa zFrD#xhT82A^ED-n7{mcr6wbhV2%n&3UL=?FciUIhrwj+$!Q3BNGkjX<`crG=otH%~ zV;9?9bR~a<$bVhyJ6ncuF$ZJ^wHDSGX^FxRo{}%*kbo*BVO(R=YQ2ZHbdi0K(qz1q zzc#5|&*i_>fcEk7CfZ&IgRfw}QGR6D2qnJ2F+!9QBNJnza@a~Tr-+7Gr_?$AdIk{% zu`Dq*hD$-_^@jSwES5)oV5h;X3|wu}R$CvH0}&#+qa4I@JszxS{Ii-?$3!^$7?-_M zNkt`ScWzHu02e73e@Mhw7CBphZRwCQGt778mzTV<;Wnf+7~7{Gl1Y(+jtQRVP2# zPv}3clGa!mrmSTzm&)#W=bQ^lf~SU&0=R@Dacc>qnNrlJ3d zQ?)>vy<0Q~f7-c}*67Wq>*@tIh2Gpu^#z-6<(M?O|6nGo1kw0!{*j{vKc^S&*5XnH zk&&Zc3dOl=iQiejd^v(}_dq#Aug{ZWqO-w8s@k_~p6bcvR6Wnit&vDB`sAp` zur=^rCf5tUf&1t&93asAO)nZgEvhQRV>4R`{7}5p!LdF#mwyNq$FAu?I4KSE`I`2F zRu~>ClSwu^hmWL#gJ7YK_%^*cimj4*uYK7v58MzoKok|`>tDIZ54Z9igYvv)aB+QAMOCgXQO%;DqU(GoQp z^*eOyq!av&X*ckQ6z8$-&c>^~+xkT-uD1qG3|pAoaen7VhkwR(2fsCXBKn}Ehr3NugHD&=T(4!~X)6(NEM|hDM1oI!YlM16 z*Nc8l1NkS4X>jvp8$$BrNYVG`JpU(osvZ>qOQqQ?v>=VP4rxmi#rG{K=jyL>laB^6 zkw-B3It|g@Hlar;wg%geQL>{UUOZdu&F3GUxw0s!?HjdIcXS8WNIqeO6!5ywqV9tI zaoWjyh*A75DoydLvrwv((4C1V76%UeYAr%#i!wlchR~RIG+LVMFGk~Sb!AfQGQ69> zt5!f7q@pECf>)lLh9B-$A+-iDCQaD`JJgAERl~OZ$|gM0D%&b z_>YrK7M~JZ^w*j3S0ZFj4 z_NdNNl%_(njvp_CQoYBGq(mBqG>zrn4RVr~NwTi`q%x=9k#-wghtb?4Lggt&<|+x70J z==a~eWKC+q?w3ggP8q#x%RoXcqIGm~Ceaz1DEG)oQ-(HLN#U?%74q|W)n%ku$(2qs zO5?E9LZyVi!a2eDZn)K4Z`TtDhcf=UIZLdDw86YRlE8y#Sx0K%0P{>;$Ly3Y?*aEl z?4+_jgy0wDS)dBT5>EKJrogDfTTk5w_R$;ju-xkg6?ZVygf9XAL^g0Su|iRR7xG;7q!AWfpp)Mj()^T#WekL zBmolriilx+4-?h^4`#%Qfb{tgz#NQ<1zpC}#6kpCoH*2s(pkU0Qksla;%)^;_E9AR zLn`r8PvZH{18V{`-#odBgK2b>n_2yCC#^@~)0&b5r*=ldkHWgc{yz(#`^HJQ_Pvij zJ|mnOn2P%+XrG$lDD&fz;F#QcSGW?n?A{f9U+ml`-^5KroZm9G=|Yn10i&o>5%IyH ze6(nPt;!jDT+(y%wfel{p(AtaWM#$UD<}APJ-+;?gU#wXx{nRoWI`jKB8Mb$4>pr77-+ zr|--ua{d=dQS;}ox${8+qeyOaqnBcOB#2)P_nqHS6xkj+-uD+K@{K~1428=X&)Ze6 zEZ8DwOh!loLJVJ{;%VDq;a$+fDqsYZ~{n|up z;(>r1EGr~riJW{$Xq_m49cl!v;Cl#&vvvfI(Oie3xU7BDl^A-`4C@6{-rb$TJLjWl<53|?vVn`2y+)}N_hA=M*Fzr# zXf|(##n)Ei=dd7ngWe?Wi`V4^yKbc7Lg&YZaJ@?~8Qo*wUt39^UDX3zpT%XFw;;wM z6GiQ9Xomodc0zUHJ~sp#Pwz6-p|T}S^ddLzzl9>7N;gkOZHoQwSK6T2MGuFI0tL~& zm-V>gm3bUU>ybCbhnW}e+d;doV;jk~?Iq%bpVUqO7`SQ&@w#o?*+K$3jf;tQT>87) z)5WlPTj%6|=iRadb{FG*ea+R>{E4+xI|h$_IVv}a^RJ_)6E^O(7){QUZw2ZjsoiZ? zlDtp0rdv&{vYfQ|t4(x*_Z20DBHsSaws-JLpQc2Y_BxYq@N-j;zNKoxBL}35N+s{b zJ<`1tOCIspB&ZgZ%NUm;oPpDHMI~XmNxEkN`L`8d355=gf(YYejd^7|V?cr}ehp8U z)*bQs%l8bq_{p_j3Ew@uX_A3~iU_b|_zxkSyyyfxx1f~Ldoh!3Gq7MeMM06b^uJLgU=h-C&e8 zBZQ4o`V8rIuL(@|r+N=jJi+n+OJ+&|3dV<1QSjYEZszkFI#oD2{s?1K>^DDwp~=pmkc zKeSWRq9{@e+Fs`H9*K55tQcukl9cx%*mq|M#n=Kd%}rL)psVzZU;DM&M>MyC#*>Hb zJH5;nV@(^Z7Y+1~Mg4r%o2EYcXI^{ROg1brat%+Y`BW8F>lUI@sVZexvqk2}+yG7o%wu8+kV$zKz$V-kT7=0hy*3T7McwVh%d=nk5rvAAyLkK-^ z#sN!+Vy5grzr+*KH^&B+bI?$p2ja2iPkV;`#VSEfobrcAgBZUfy%7D`O5Ki4h5N0%*FQn( z+w8;MW78E3@_&k6b}6R#NGlGC4jUn1XLo_ocB63<5}c!xbyau=)Vt;xLE8d%lz@lV z2d0%3IxEU^H`s_65Qjq^=l<<(Ku(w_p09u%=L2%&A<_Smcidd8_zKt8d}FKt#4CjG_LAMG#9a~= zipNdddhO4@lb<`yxv#Ol_;J-9iY>x0(l%~XMbUg4J24Djo%3+&q^8LF&}4l|#j=6c ziP7<@%Cq&!Ge(F!t^mv77T^mV4CDI3W))g7V;uezH|i&gG8Cw)@CX_K3}NV0P@~8Jj?X!&k1}u zgtzI5^dWe+2$h>DpX*NupF!Q>{a|h83E{=F^}_CMsDKH%9uR=$mQ4C=;r0Y?Vaa0$ zOp_*)o;kENng>V`VbR6Iy}e#E#cXFdys%nS$sAJ9xb=!6ai9T77n@aDMZ zON7HV8lUlbzEORX^gqwT-B&z{>IrtG?Qs!K5aOi1c7Oz$NpF)%7rrCizrbaWJtAHI7fTr|-x?SK^^Viu>gy8{BVnsb#R%{^JsV zs;qtsH^_gEI@989Snffz=*bYj7-6V?N>g}E6E06r$_qK|J3W1Z&AETlf;&AnvH?bO zkK<$QSp<{0=9r-J9810ubEs&+UWopKJwz6RKY^~{)&@eB2YH5R6F>Nf`e?`~7%#;c zNYQ}0ksHmtgOaUa)GQjq9ei@_oiNHa@Fv7=t_)&vwWd zVZH$4a6|4DHa~39_z8s;I-1~h<{&g)I)xDbj%UO2>=M%s4n)ZnP!X>Ep@&xt1R?MM zfhsaw+qlGH&&HyeetT@uh8zXW9M^m#GV1_I78B8veQ8!zZ#wOQU*Mtyi^o0qIro)+ zr5pffGQdp1WZ8Qb@S5mcraPM=XD}Y5WyB7MhFTU45+8gB$KK6tr2_E5E)UTV%#+wL z!M}yMei&^|5p644;iUc5#24?uC42YSxTz*0;?b6HG2v;6W(+zm3SW7lyh^B7&P$!M zw}0Tgz7#f!1b2&ESRuW>pQD;HzVm8;_;5aO*W?pu$o%s47kSIs12QhofZOy)v{L0q zJamSO@H6F1cXG1te2)ll&pecCMPpEZ<4m}~!B|O88u`lc^}4-LbllgO_9YkAiK>53 zMSki(&VetFUL8ARkBzO53g;cw!v?oKJdFLDsEW(r|mRT<81n7YpWT=i{J6X{XNFkZSV@E%Wz9 zWEGPT0{f2_{@(H1qXI>^5v0t)1H13_F?E;0+Qm+u`%!*WobK0r=i+_`20q&Sh;a*+ zeu{AmPnzMl0{dAF+1jr5vM9az-DcJ4kXpaVk=%H>vC?WC5)a5l^janA$|RC9Kk9X6NX7ujHgG}$c-Q|;hvCAa=MJDNUW#&-wt$#ZoQT!hvrr< z&SP@NMPD`UhR^|3{jpsUSvSABy*?6*U^~=^=y~=|6WiyU)<>p?_0_wm`Q@|`yYzvC z?USGn$(~yPA4;Crk1W_n3^(I(OUys+SbNxC;}fiNjoaNNP`l_Hcbq_otr(iv%%~9f zQ^DN!-m_gI=DF9xPMDA9M=b~)SN}RcNKfLk&N0){tStDI5B%V}vl|h>8x@=B+HzKH z1_4sE=XlTh@T7>CBd4c_M4Qghe>wCo;l{)wGtH`}xti=jJoX?xh(GPTz`P`5Pezdp zTKGNGSD)IHg}SdQr>_sSR|f=U-I?s<6^vo^^Ij_9e57wb*h*~wi-sbF`@R<;8!-g^^v5L+q$D{Z+#m&cEK51dAiM+cEOi02 z3FYJOl9w8dhV*Czr19bqG2`nHqaCk5$SXG7Ah+gI)nf%p@EFDcVS+P_khB3YMkR$w z4Izd+pcHw)CxvB%`(i02)+nNk;)o8F0-Kj+t0zFHHw4W+aTt41Y(yELbYgd!YGO|j zi&Kj%ij`^c{4}bQs6x`vV=u~CLCs!dXnFpbmB2SP{%q8R=Tw6L^oTI6r-%N8Nv84w zkrjCx!T06O+S9YST&bsb6k;&xU#v@>*Y1MSLS3;ht3~bl>5BPzqWH1`2d+C)JTu=~ zJZ3z-VC;{5vBA$7xQ+0I+%Txjh@PKn!DMvn_w>IF=#81qvLZt`9j(p9KE2CjFA7ahu0q0)zO>05*(a(n=KY+DcWYW}5<}Q@5kuJJ z3cZ;QYzO^DFKx14g0d}~sBg^lBApbD0sPFI_i^zvLpP{4VhGFIzFWHIBjv+;a%+B} zL6_NRf=Yruy8qj5@MT%|v8})FPR#?q^y*7zW5UjiDU-$5yF&-u#&4z+90+Yzi^Yb4 z-23SRZt)U#-3Q&`rS7Gj?u1iP@b-m26;EhDuFxftkVELcXE#g!SKlj14v$+U83g|4 ze^vz2z60-(prX55R-JHz ztJZ5L%{v^+w{De59w6<^3&kH!Q1~6;AOFIA@sG7BhlXWRBfi+3L)Ub5>xp{X2djh_ z?VwF~Naniw-4ZtD8Ah5q%YN<&W=lYQL<%K&{a{I{BRK3zk|Bj2RoZxB&kUAm!TB)v z!iYOkE-%WLmwI*)U&NP3q5d?;!IDL$QT=e)!6>fkqCz_(GiI`{xOdND{n9IlSE2R9 z3RY-9)z#bBLjR%nr$i@uK2Tp2UdE3QXhSbAd(`gU(ZvIY3thzoO~RU@qWR0TOQ{V? z@rVDl^zf&X%ZzbS>H&Dp3F)adx(`_$`Dr0H~bqJ!iH*@?~QCop8hB0lb}M1`4g{lCtO+0J3rsA z?xNJPhJZ2m-7Rhq`L|!E<(WJc(oXz`56dW&K|q6+Xr8(SDFsjw zp#;dm{`gBb3t!oxT@=(GNQ|q-^9q@4f!vd&=vzg$(924o?1Bqowo9o0?iG!(2%enDG-sr7z5FADvz84bc@$AN|61$ zk%XT2^9awQzX}bAV4ws;UBFN&<~^niBXGLAXSBcnNTF*~DxJ3}CAg4DOX(+{D(`zb z_nHqROHZ3rxRnB!jPghWurX)g9W)r8-kNE|5FTiXA*|`xszWh^LrP3PaTz#i;`8zB zywt!WpB4826oiThu7mUPO5&nZ4Mc`;AwCK?ZY@7cS?me%6#WSo%pIO7L)bb+OqU@{ z22RYKbX9UpdpB5IH@po58Vup+u)F3x?#=IRoi66sNL=Yh&1q)@61N%iY zl8_Ld5CJeD5CnSA%I{Tz$3W9@U0_|DLScFh{w?*6f+9$-5L~?fJ1JF2U&t%C4ImjW zJLKJ{)DzBBh3A3IHD9e%X`y^f+Ai$3by%K+g=F-S#Xgrk>Fjg47gH8-&r1U-n}-U_jj+Q0(Vm)+ zR@grl?Hz8( zDRLc*W&Ud*0>b%!4;x+qmZF%5WYM6Q{rzKF8g`70b5;Y>0fa4$n1Z_q20~b(@|v_9 z+EpJ^X3|cxC}5ay+3^b*4F>fAa)2WIYyJJN%IcDeVXz=D^9t6Uuj~=zyZ;_}`hnv9 z;co=(UUyZR9T9v;%hqS*Nr;W;HDS62^0R(|E+j4tJcYa6mIYvUvl^V zKxU!;P=g2^v)G=2g7wi41#+>Tt=R-ho%6xz>2^;idmN8+E`lYS?XO#A{3lgH*vznMw8JA z)w5tu@<}F(J%t~2h&O|)VJ!1b1B1^`VaW%!D#U1Of12I$HJ^v@8rR#%p`~VVc(K-* zjMj+6!&%n=mWqT_#c>YHOd`0D{jXKUV#$y!-V(|aP6m3AgoFWk5#+T*CUV{B=3(WecF|F<^}CAkwHG>&E}KwYtoaLQ6FM8p=)evKp?i1*tBPs(?*u0fp#q)_C?8{Io|M-#O zX+4Ge50-m##n&#%ZBZ=KCm)p+A4Z`9d8!Ela!@f7^+?gjm{Fq#h7z!fYE}83-r;4- z59AA_+6X$5kENp;Fq6?0=QUUa@Gn~kDzoM5J`dqrvduHC%VhL$6DFf$VolF<(%8TK z8puYDIsMmS9MSgQf%eQ88N&AHxzn?N04?6kkv(!RjPYhVeM6=*|I`@5{dGZQrZeZ5 zJ_Ii3hi85uB*F2drBP6sNjo(qfIS{NY{;TmCe;9-1!%_0((PyI}`ouEMsK5_ZG<2K-huphBuzVvyw?qp4e80jcZK2yBk-~PFKacAmA2rPs` zBrFXA(3lL!YO%>w&V~omxG%PT@E(*MEFbonr=F9>gTYwTEJ%U77;|Efi7+p-n8l29 z|I6+l{vxFoxe%B-lLzJn$`O1B2&8@aY5~Y#^9l7wN(tbiTo8XVW%(EczeF0LZkXu0 z->(v7wBPy%nh|ScP@=JdKuRLh-185b0!r;yK3KJ}m`xxs41%NGizV~^XvWa&`uxYdHV+4WEGV8l~x z(?H4)Hj0B)7%Qr8J|0yWrZ_yXCLy#5&@f z?a)AE2-~6MxiSYIY0|~;v!WFOejK|YvW0Wy?o7IlDKUfxx4JwGVN3rd<~L@3cwYaO z<`}|n0U>>O+%oZ(DL2r5Ig7^28fFa#w< z1lcA4oFtkjAH5+@+Q0T?MUKH(lok@%8;eN$r*2BK+tVG~W$Ya5{FmEwbBXXtTn%ot z75Frz8QfkQCkF7w3*L`#FGD`6r^z!80FsiW_~>qwsgaQ2x|#xtqw%A^tmywN$p}4U z0+&b&0ck?Pl$3{%YytEl+D%w3O9FW^8fY-2OyrPpz~|fufLOR*yDxrBMVcY#D5a8` zf;DHrZJAep|Lc z*le^DNyc+?M+4kh$O8*c7$e8bo%=GID~W(`Hnlr9#|9Si4++SSvf;NPAe@_bsllo+ z+o&lb6)H{HI&GMYE+jz6KHlu{*l@GI=c;WFT@ypHqKx>ru?A41!Kay9kYX|lz@sn} zX#tmt`*%1d%sek!==NV&A3k6@(KODFX>ymt$Ug33HU zOa=H?THB4EA?<4P!AKeAXPZv+=uQ|fjWsHyXK0X5kDLef&EXT>>u<(bbm{Vg%a$J` z&7gp57UJ6S;``juz?1>uBK@4#!eW51VU*GAzekIs$!H6e-man8C_dtU`GPipJcxcq z?NWRP=ZS!@gUavd)W#N$%?i-b1;xoH(?C5SoS?^S0KzaGDeosOFSUpvWbbZdOFdb^ z9-W;!#rE`u875s=6ae`I$HHH^uIlwSCCwO|gK0FF2P}l~3n?Xlf`pm5`36yf)R_ew zNCm`*JjLX>W!NIZ#Tgk$8g2|efqz!QI%|*^?N2-?)JJswbFUZ!|17x(@>%v6Y7rYz zh6Mp;Q&0rT5#+{;loAxgc$}=*vv>X#IzqVKy^v=T;p~F{<#vZWS7a-+aSUn#AnkgY z%Zfota2H{00HXA=`_h-w`JoavqU4-#139sOq@JgJw5;%?WViP`p{1GtF_O++(9u(i zz`{o!JV}r*W&AXlA;WZ+KE|bxHZn};y|4es@)d)9i-v2VtOkf>?rETTKsZZlp8ybM zXN-U_tBrY7-~E8X5XRd#k8at_mKuEsXQsdT+nX??Swjv!`P=Ss11H2p_H*}^g5jGl zM3k*fOy7Lx$t2qrWfUlgD;LotVFJm29bCL@fo!Zn1;mhKD^F}m%T7Mo+T(d~Uw{xC z=Qcm=?)|oa+%!^C;POXDU><&nq>FgZhcyV?prxQNA3_AEfC*{jEMm9|l9Yl*!jxZh zm2N95VLg^69wSeC0gYCzPuGdS1K)Od3}TsylODpn@E`@P-Ra}y1cyM{!Di+txbJ0+ zj0}Ey4226Ks0{h610n6m(~Ad8UWk{;jgVeeSP7{kIK|Y&JLO>uo`HZja@Nxqd5gEn zMBltsZiHaGGcHo2`MA=~nt3w6b*uYDFApZ9(Ei0gQJxHtFqqbYn%Z?CylcDLzaJ?w z)RS~x@}oXy{lO9;Ny$M^9zxNBT}m}Uh*5B$64^_>TLOEFJGUCTYod8Tr*B8Y`Na_Oo4+=3zJz+HRL<~szB7butl@Lm#Iq64+TCR?v06n8a!DM^ z0#BA*z2sKa07#&2cCK)J#0YJ^1d~zl-W#rw8(~N^Z{bW4AeqG3=P3*+`RExO=xEsm zfl?4_HZ}KGBw@u-5Ey30z~k9f)))zg_1DOAMFgP%aY5_x{8-^R2^OST3XyhzS=JvF zpFo~KT0&eoq?^~b zh<%MD<$RvVF@wuj9FUD@c0F2CEYsCMxSLdXDtK~uTFj7PxxV=6@0DqmW4O@rM;k)B=#c^Sx>TF2W+h z4Q|?~Fr<|0Zd52v*ftnBZX6UG_ZkX?Lk;3HDDuuBaPFB$)MC^e91H6trf5y3LDtWY zBqRd_MD2VorRL~DYQcSb1hHs0_L%7)0AZDR#^|+YhkInBUtBw1CzwzRJD( z#`M{v9rh2l2i$noyVEYLmUiOYpu_GST@=qMLs97d*B@0K7OBG!8`)<-8tl_-ZE1K@E?Su~{D?N6h<>L!P995P=EJz4?yj-M_`FCuS8z-KEA-fCelo2EFniNcC`yS18u#Gw30SE~MijUvK1p*M@ zN9<78KOi5kf4o(7+z1(=w@;KKd?2i#MVjG80G#aR*0Xl(q5tTgh0~A;#X_yrP%Erc z)bS3Dq~Z?Dzj@h$`Qn91RW0{gkH^-os}>Sj}t4mQ;6A< z#vz1ZU>9kp1(FjWTH{{Gvbn&T0<~ASC^Gi0-Fr{Z$h!3}k#1gt z!_bC#O*8R*dK%!aaqI0a*K3srOg~rEg~^@XT=Z(5AtdOi@(|8aP?>d;T*2bzeq)+s zlz6(;8o*I#$GwUZOCg&S`@IO=Tdm{yHC_aS^Xq=KWwpSaIw&Ml`Yj)%ausMF{d!lIAQBe?J7ml-5{azMVqQGp#xDFwD|23_hVi03L{L z0$6B4WpEv|3Lp@VG_nzf#PsluoU#JcF(?&o4Ts|;n$H?@hPW@lHg?#d@H{{&VyIbT zK^oRirUxFRPz-m0c;RQVKNEzX4|tpylV>Swzsk-Y6o)*$K#bv;WHf9_k!N<|aE5ln zfd+Ru8`_Zvta8Xu^^mgW(pa-4vInY#r#I-qU(x7QOVTSFEae{=!jv@s&>^fzNn}s* zdXV7*_mOVSbAra)_&PWc^HEaFuUfkYcfs2A1YO0-G&I2N&ip#U@3asdHSs=iw5}_DH;;gsj96F zsmW+_bIyjzXf-i?6H!JF?Q;327zG;cHY4<&@2WmNJ$WgmGLxyZ5t6UF@XI3S3LnZz6GfT zl{qrxe)@oX1wn?C@BCA0bV?{uauQOw7u+uhJxnyI+pS@i^REz*LLe6EG*UvM`ETA* zHTuO&lua`RmdKAB(UY*+2b+;a=z#3hjCG+qcFSN_mR1@rOWw zW--g)@B5=#n@`{(vtZlFGJ1^BJ-i<-D>Gr@l$wIX^k?@HNJhq@ zuz@6|A1rQtVTH0x7&Dl@6G$dmxoY1jr|(?6CHyI;G@^}}%c?5l|zO{gT^d13*F(<}T$SmKdrJ~4e)i%ouFP?_o7xDNK>=l}>wW`PeDXn!K!t7Ab-$lNi_o14TP_o*p^~yPv0kr%KxIG@!uyeBzNUo4 z^p{>KE)icrQqq6p%d#4!PKJqaPq_sR6U_sPKwR8hw$Z$7Tg)LCo?C`RXqJ>?cH{v| zS>BAsu+D6NP+KbV-r}7A1J7piW*J*AZ@ujOci*7Dtct!?SeQ{j?BG9kTiO`@AkS*E zR)XQ#20fCfFcgp^Ef9>9>@y$a(OV5mNekAkFrsj(*q0jnO?Ph{N{CT%(_=@P+cGSx zQD5%6_sk4KC==5qOAoDGw+DB@>U}ZM_&yU2gs&Iw5qF0>+k6Rqr~TCw8N%kZ9VPiq z9|KX$L{I;FdjXV{X_vU~2VZ70{oF9`ajV8@uugtTx9n%V|r4OSQjEXt~a?JMmZ z^56kqNn{UN%feTCAZwm&)&`_xeDLA&)nk6VppnJbVBG)_Sr2$4TUaNLv@hf&RP<5r zRVY9>BKUXj56==H^!B2?y~8K1e{uQp1Df$2AE~BowEppZdKw6Khr5>jAz(_Qh3B7J zW0uBK>MlSy=vLJISi>NrL$xD?Z|~X@GdNE35Jn%u8R)PLU4eo`3gl((g3%SI4LYBn zQ$&-|`FY>kylP^QVm^v}$iW?oM2hJ-U;}%DSlX$9;XxnFja^<7FN87iEwnUFEMZG6 z17Wjy2zwg*63I5&GPaSQjlhiW{i8IKTa6|$BE?LO{WoFy!oIvlCLCf}hs?Kb(NF;l zgtJuGPh&|KVpP_cm}VtoJ*xq;*hIIR{?*;}RXumB*C}KuMJA(r+&LEs7E<4`*=@W_ z2?n`kAyorB7`AhOLn{OVWgCsrCip6wX^^m=OuvsQ}Ncom1dR zEJ#G-6Y_fq5@tVac{v2rWa}iQEgrO5J#A-y{}J66))Q<{(-GsJscWF-?qF%$@H>Zrk>vT|dyE$qp10BAF~U3sJW)LV zM7uQ$(kXp4@o(|CCZnUZ7Z$#~YfsGJSSF)IZ*a&%JpPMJ2C;NX1MJqG`g^zkS!ImG zUGR)Z4|eKK%!7F&LpTp^(i~c%QkQ;RDGew%8E*KkIkdI~zZ6mnHeZy7u&2cgVVJ!c zocYpE8Zd-xzRgN-Vk;>lSlGe_gS{~I1QkMzU{IGe&#M<^i}rV)l&@C}8&fYCTe2EJ zZ)T~81!+h#NDxt62XFgKnok0i*06uZ=7GxUSvw?gR)km!n`x#n`I=|L*j=oJ#|uJJ zV-afWWS`BX*-{^=g|p$hsI!tR)x#+xu^FF7F*|NDw@$i1cc3K zDawr10KYly_*aoX*dD~vHVw=jKp4EzC%AS1VRy!4l)Vu=5> zWO7)8%8Y&lYSM)#ITY|AEi5CuJQM{)1Rikh)U%gw@-?3Y`-}jR$4g`n%Ej=NSttRV zP$#2Ca4htR>0jB`f6UT@>3zwrGb}h(rm6wHG|X%meP)4u%{V;m_L~R%iP?Zsed_ zbGhqVG5LiCK*%?q`G!F=^W56mk7^Y^}cvz!>0H>`T z?Xf?$!d94jO<_A5ST*1o4xAjKaBv+4a#phNFN>pS|Cig{FaCNO4m2wt90;@UkM-Pp zht_~CB^0sYC8jWZ#b`D6*VfN=97nz^MHyDb2)HkvaOM~qhwEaq&X%1EVYOB`WELJ& za3;p9fij{URdBta0^8XKc^Uzk_uc7w$EqSATP`F(I0i=^Q&K7n721K9AagD)3r=Wc z*;Wk7hIOW`@z1n0fb#7d3~f*RW0rjdnexNKP(LR>o#0K%vxgCK_Gbc<9Pe{cKh6Yz zu*QcF2f}UNcU}GZ_HJPz+FWrsGK4ME=uC%VS4P4xOhc_Grf5%fpElFcWB&!Nfd~i} z_ziByjotoODQWHes;-X{;UA?DFH&hy@>~Q($zI% z%;+!z!WpTrrJdP^S>za3mM>5EvA(5~#K9J}1|lF_*!Qqes~dpN-2UnkDH?2TqW+I{!lK+bnQM4AN*p+FETB zVVpqniY4#gtv+7M$bLl`wf`bC{Hkx*82;Bycr8a8uOoyr={t&AKW&De(V)+ z9%${q#G?nbfI`2^jgyD)sYl$mZ+B1sRCa6GU>;Lgx6d8NZ|&@s2$f;G=ZU+sbvD~S z6PpG@m>r*;HzW`H`x>e$D--JtH4scFv#LXr#=>D5$96V*LyZdNM%R#X7Pkhh#YQ|^ zxGxYUAfEukI2-O))(+Epu^zVR*~QS#2$qque*ElQX5Gqm9L~+49cNiE-MNZ-Ge46D z?*%G}#}awaT0?nDe9wi0<*Z~`$L#pDvjCoO3gfdRD_l7ElUdLb*Ah!hGyotsvtjg{ z)%L`L+mkl&6V-48yRAIBla}z|;$a95w8jt~+bF0^sXh;3<=cDGxtbT?ANpo|2>aJI zKV+1gf(F=b5jKXxzxC_h7%j7=pt>m9NCOcNHquILo1q5yhw7Eh?p5!e;V`lL7!6DZ z5PCXd%qXoms0W05cDt{B&OP!Y?fA3X+-c0lP8UE(0aX(DBW%YT4rNRWn`SErXE)Og zyG+^`Fbt!aIp3sRqJU{2tGeus0Jrd9m`!iitTDj38dPJ>hrl_|R5k>EkOxO)ZS&YJ zGXek!c}@k`87%I2CfVPIMOx4rEG^+4g9RyPd7N;JL=qs!;}_5u>j5WlwgxBA0_wA% zFCf+MtOlD;Rt2FK+7af(hMvMw!#WM!(a7SnkdpOF-iICu!idqx#nvoFgT^vl4e;m& zGvKVfaWms_FSsMq_$dl6S#E1HfY6q~EWB8%{me1^tW0v61cc38$W&zn2uCIlDiZuOVjy5t- zmc@VnD>8_^_M_sxt(_+jyvpM@GOWb$7`QSZg(Wc>&n+FX5yh-DwBtrd@^M|l6;+)e zZ-uoP#bmmI4*mQM8jZ`m=uPP$jERjXD?|zF&a5sb9U}gjmIlx&kHP0|khw4S3wV#k z@07~@-$_k{r__r_ht%dTeyeB5;ZVm4Mc`;#wv^hOsWBL+3$HI#+#W`Pm>5tl_AV^ zPySE!BvX!aI{a&N&mHdD|HlzRriKX_r(aXeY|xD%%u2JXhOwcrd&Av}_lD)V8^;hn z4P~a(2s8yJuyq3=WUU9MG|15@jM6NUO4ewT8wbV)?ZAW81fdC$QEDtm&Ek{?ti~`h z$Y=Q+5EMKQQ`g8dFFzdA2d&{@GYerJFl68cvjiPjl-1HgJ7*2raW`QRKlxiaY)I%$ zaB114g6oWR98aD{4i(vB|Npc1CUABY*PVa8*Na-cs9P4Sx^CVhd|)ysFt&N1z4%*nBL zCr~K>z-j-a!`$cWfF%Rle-Qv@ZVF=~EywogICBXTvV2^@CFz($;lP^(Sh*S%LMWtk z=nk<6n(Y&}XW*iPf;8BH2OlEJorF-W1pF?ZY(PKgk?&2GdQ0T#3 zj1YW8Nr4qwI3A~Prt1Nj>TgLpMR4-OC66M6ygf^Ssidf*DY-O~>R{-?pI$4hSi%Za z&~(KQRK&KBZ}>oVGgXiq4z4&H!tGPup1L5wfA~-4(L1F$_fD?1O~CC+Y491Z7Mthk z7fPLsDBaW)$I(ly!>T&X0ueD#)4aAta;G#V&v)82I7E_5K)aHGMAv8+J7AxjiBAbb zKF_nac1JYQ{M@{_823J59=|_Irt0J_qj{`!Uc!U=XE&RzcbL)9tf?^1Wfb2|W^dd( zyEf$UnABx(8J(2)5)|eKmrX=>ZjoPJ7J#g}#H_y}yiZRcxIj{k1cHUI8mWacRZ4*0 z53EdVIYZ#A!gW_v$!C5RJG`@k`yP5p-Uruq@y63PnV&vre({v(J*cObc{Y{`T9$wm zg$V_#qEON6`HDFE#3*y_4OAX$nrv}P}8DojB>#E*}Xz? zT~Lz|9Q+-07}BKk?HfzAh|&Z6oHdfhP$|Hb0B$5Jgvm=lyBNXh4CZXJljN-3r%Z4n z;LVh8-F3|AdRED*VbCS!`8K=siXx0>-J2I9A*MnMhItmkGUpIhR8byrWFcIWmz;kY zwhzdcNaE{f|4q*E0t)gq0ngc>T zdboTWlxFydx%-D^%l9TeXdaadWmBGyQ2K_5>f0x z0yL60^eF2-a>%0$mw6IE7w3cM{PVcE#7`0rPo#=IjYUxd={I~qjBH5Q!8Wo;$L_}~ z0Je3Z>z(plYQZNMk0Oi^s%B3P*I$mFN~v8}=;ggx&>}dLVhMC_Kzy|3zZuc=b1s$U zv(At#4b+aIkLq|RuKBI(4eByNAOWpH0uJ>-uj8LA-;p(97yeW(0oP?j=obdVWG1M* z`h7sCS&T6z2OXKz$a@VY4I+i1hRdFP57IYWZ5A)f)>ae{CZGSajB;ZE5a!CG_E$k! zs=Z7D$C45VfUu-!LdNt-;Hhtk!H`b~Wh77qAZ%JxhF{XG$G4grzh(yah{B5g?bKFR z9z_RT1br6;*H?O=MAbg!+^h=jicAgCx6A93=FJoe$Y*5NC6BulOvZ{1ySe; zd1J}J{=(M{%1Wzn@RE9A#a;MVmrH#=@_Se17}ZIKm?C))QDFm|*`O8NLL`LAOTZ!j zye^wOXXQ``2$OTh(Cvm$@=~QJ8CP!A?i=21UUP+MX%$-55CSd4XQZ=K(Q48Ggc&xK z2^PX?gjc+bE*CuM9brLDaruPQsgytfgi|Tqz&nWq*m6b>S8ZQw)?Z%ZU#uhzm@PEZ z4+x)o+}!%FhHq3B-}%i+%!h5zpl@Mm(ST|KK19JK0|=KWH-=KUHf0nXsyDlRbzcugTCTT%j4hXJZ~&xGX9GJ-sb&XgQe8 zP8)e}2>3)1#u7+L``wqn?^j7WgM>ANXzI}WCP(M->tjyn@ilc2l-8=#GHvrMlMD=n zjC?MSU;H;F&|~u?_};B53Z?f=RX#*yzseA5A_46(z8On? z*VKf$W1=I|T_%qdzH3NcwhSfXS;sj>LSW%}mz1HMR8|0llM-KUVSncs{HOSY5F{|Y z5(t2BdgUEzD=Gnh8`ADG%*xTH5axc>Fz2b!gY0#fX&Yz~CP8ZVA!5|N@TV#XxY1H( z2CIs3kwSDF7GSy{2@HOJf^`qqiKm(OT$kfP>KC6(eB@BD5KcyZ zQCW<)JMWdFxd<#51PZcZFoYn1X_r6%gwrnaP+?ICFeeHuwEN9KAamm8;5CsWs_6lQ z!-vh?KQ{OL$Phu(b?c^bnqp5yLq$fXLErUN>O3;NWFH0eW0c+G+p-tsGewDtY|*QL zCBO-8sxUb13OwK-icf}7ktJ=Yp-5wjPQUQ0n=^654w@RUXEUfJ$K9GUA^JF6SKYTqj$rAO=YkN`+?ER81~T`RYR}K4*gAHv`GL?vY>a5 z4+Fz3BV>CU_sHJ0 zCHKg{=6T^m+y%xJ)0aPqF-z-wJiWonxw#VJKBQ z2?Rh`J6Q%!lb3)lp#~YUJ?0tLO`hMJ;&8an-j3S}z(xGKj1%!cVZ}(3S_s*gU(@*} z=%rsOj)Mbl{kA~C@<EghXEVL&NCHL2}_nS@oBC)0+NzhB2ewJW?6(dUW= z2R|IlC`uL*3nicn^U!F0_~+#5FU+GXN-$QD!h`1NAXIa5eR?k0)dSoGuA`$Jo(H5s z%!fd|Txu@g8ql^G9&{z^V2f`0k~eH%MFZ4%m`a_x59$M~5`26DfwmSVHL(;$jh^3s z7%%`cWSe9^9>~157Kv;^DebN2ZgNt6#pl~{a&~Tlr|m#!nL+!{L>@9HA=v@O>B$T5!j6Im6ZVd zu5bIIpg}fJ;3ar%S9oTt39%r7L=p&qFp-!7(X>hcSa_u0bZv|(m6vBN)7pUgtSkbA z$r_gf2on@xq2NtlH#@iI>%@gcQ7`bsBNVQTDkOF(C@XkXZMrn;8R)WRFoJ4@`dAUN zMYGqV!%H=rJ4Id7xALXTiKWWU^K=LQ^0ay6$+-^bxHyHng`>zBn;V8Zw0VFQ9}TMh zLd?E3d7IWadLMHtJ!*7bqBH2_txg2E0^xLn(>&-16H@$Lj!4n%Mi~#BM&N*lLPu_a zW>c?&j`Mr~Oy>3xHA2=d0Q0-9$>WL48D@~tk955Yz^XN;Om=rD7{dJD?eFPZ$#Q zRhs=zo5ls^Uwb%JIA1=_WumB$JnREGhu;V|UzR)v2OcWdDr zLRkqg2Hc8Ge{AFx(jN3}Ym5!u1dC1?*eT{ULQQP@)TP{DNY`VXcEdQYRmm^8P0%32 z#vf*-iYqa>{_&e!>cd6u=1a^Q-(?mrwG1%#Y0w`F;%W@kboUG5A`sa4$dEDYGO8BB zh((b4siNtEWgvJiqUQ1L7EVnx;CM$pNe=V2LfsanQ2 z>Y%@^Wtk!&%SoW{pm|+DsPgnjAl46zil735e*}nwe`xujFBeG1RzvT@Fpr+Kd|*Ww z0{om354}1f=Ai{JCt2v+sOkQe9u#Mj7=r&;fe>!^yx6AvHHWTAAyS0|9LCENbs;PF zB$l_WxtBQpON2sh)1RX4r{3fZ(^pr8GZn0y2kFIcF&AH6{oMpWm|S+e)PCuX?9MT- z`0#vx!JS-mfpWSe&~W|r*H2enp`IXtsw9B#D6aNL`{l#(YeL6FuOzFgr``*V@;Wwg z!0k4bmUZey15ofMH=1w$ofrnuaX3fXFvX`_?iMUNDLu~1Wr8DY`sOCLIGX) zePZ0 z!IP9_NH9bhsM<{w0qH%zO_rs7_1UX63pn zJxIq!IO1?(U=uB6PtxeQNCOny{WJ6Y_stROqRd*s6W(T;+UMe}hI^Xb5(t2BcK6@B zXgv!E!Gx^3R#-UnlI%yy^6Qo*^Wyg1P1Xt!KDO0-{R?uW#EEA`I&M+*$km${LBjyp zpcz*bP>9jj>k1J5;7ew8;0-zCkm;(Ul z8qk^o2JIT?zwzf{7~~QZ#~TndYz-8_Z5Ym2ebKgw5J*%=$t5pYXsxEhhvx-@p?mWZ zaS4B_l>nl~Pk}Bw;mnC=Ftx4GiNEs|dF?e}ShPey7cYGn9 z0d;tdvVc%sf7K%w4IaB3f@N(OLzE(%EU#)k@Qg7JX8YRp(go^zM;3{62e1v!3gNUa zXh;M}x_2L3!VvFJR*+&Xq*aa{wv2Et{l%p;fYG8`5LN1#JfT?TCjk#EqDHXVaY?2i zo;XTXB!8@DSfQ!NcT1i@f%EQzFcs4UWB%lGBM;KYA2b|I@x}@<=M0KvR#c6X4i-Y7 z;K~apUTirl?kF^J?n)p4!nxbGbMnp>_Q-J*tjzW|Xa*npmvi#Q<)*MPB@em8Y#(~h zkIh4OiOz~X4H}tbKwHY&uAnGGbZ8W7)ad#Qyg{dhPOYD?k)q#Mjv*aeg)1yt!@i-g z1oVPkFLSL_|fR>3b78_J132KQ-LRp>$ z4UBC?02naD^N>zKAq!zb2_QFxe*iN;oimt#%@m%o2@RN#mmS#j806qItcVKC7>dr? z1A!tpwKX|YEi`b31Dk^8z3k8$bwgSQ;N9@1H))t3*d-Ml;zL9~H^eKI0QlS)Z0WD$ zGuTrPOH~~BQE6aisJFmbn%FIq2WA+5?k!)?O-c-Pek`7Q!o2aFRW2+nU(wvo#TeLk zpXuLfR$nIGOd5Q3Wp3YoxVu>{fdB|+c?X8(^EQsKZ<}Flp`Pvo1ACoa6K)zbwi??zYSP%YcWm2@Z8WxR z+qP|+jh!Yr`~A*!&QDnDdDhI_n3)X^KqI?6_~jZD(q)I5OZuFh>=;?bOv+nibaAB1 zP^62`br!G?uCA6UlxTO1N>ad6OuS|QjPfwB2uY=v+YLxGSBkO5=b;vd{nyF}LE-Fg zuc|zcIIcRSKQ)O8$+tpi%?)RZX*WvLNdc4c}3Ww@eC_R^#OM33yYD}TUpqjrN62&tT|8V+one>;ZkIwyRy#r52M zn>ZQ4P3D|)-J|3I9sU%SOvJ1V(zypmpG16>h2}u8{TciCaC|Gs^z3hnmCLZ{x}DFN z@5Mpf+XOgU;&))=1SVs$T2pP_2`KW~)epC84u1dXY>2Fx<1Bm8CNih_8?%fGJwm%=m?JnpaJVj8{(I zJnhV$g|sJaBh3Uj%?t-71_xiiig-nI%}D#|{Y!ks_I=u!^e;JT_75;PNqt@UaypBK zAkLKT;_SH&K1=;DJ=EFaH62U4*TO2g)?LzLB?Ly!(Z9Tu+n?ntB4MQl^^TbZtLliw z+|rcLZ!7%`5Oc1Vg20lPRMkhQm2!Vxl;WIm@)*XvLAWJVUp96;4)UDxzsDOE7^Zz= z*7@!XsbBhdz!p8oqcIQtMk=o04S7nO{Pm5{O@>%OKRn3WYRS`=j?OXm`}>-H54i6B zo7S9D;t`r*9c1xo5v<*}(+~2l0Rclrhu_UjFOOD9! zd>D%^_Vsd0eP4Ai_cN&r>=}9=Q{`z>YXR17KF%!~4s~v{!5~f}g8~I?&-$us_DKkq ziRNT#LSQiZ*Zq8O;7SX{_HMc6WB{G+Km&SK`9yF(AUz=Y50_G@I|jwF$SJz*rc#LH zR6{E&#)lL{(WYiSxe01wcY`>LdgBXH-Z5IPGAr1ZI`u@qkN^P~n13Mh+CmaL@k9FC zxA^K@q!Ny>F+)3Y{Jii|U<5n%bZ!tF(w~3N+$NRvJeQcH zM=1L2VCjm``F*z_8!|5xMjC9fpGouI|6Y|M%LlCt}kKV#6E~Qj1pswLD0bQMj)knQuq|4$};|4^WnkzK~FzS<3il<#&dP4=sC8MDu}gj5zeO z=DpE_$^#~+%Wxf~9BmLr%Fpvb+bbGK71)tH1gitJs`JgNf4TPd**U`(%h}CLZ#rBl zfQ#3{&e02rvCn}&=W1jyla`%OeNR$Z_~N`L@MraTpEb?33_P1-+|ph;jOF#ol#`VmAmNEmHu^HANxX2_jOiuJsc2htU;J9iAZg6WgJB zf>9t~nTjY8)S)nK46Vw|NXR?0)`X75C?PUzhkhlJK})Cr#Pv!`SU*a^klp;uXnK*o zQ!va9UE)r7Ma|T+CSNE766WiDOv~skeF(0P*`W!qUf=yD>!1aMsO{Q`Lo<3;FAt$ToiJx9GXoHjTl8lSH zgSoN&59k8|$TDMpy;J1APdR5>>vq$x+l6FF$hWWC_kLs|`w0#OqUQ-I+5qXrSj0Gm zb;ORcm=q$Ai+?-`o1sQ#Xa6CchL%29JR5iab@%2qMRT0!RB_8(kaa4v`OBxFNS}lq zTtx!u+zX(nHPZs?Nsdwq`6C%pSKV)n^HW6D>wyd+1HhXOo>*GlBO>7H{tbdS+tKy_ z$MM7VD4qnh-iBP$1>`Psmu<5b%3RLMHUK^=e+M^fV|Ngw63%mJN-oTp zAh?qVc>B)es9;-`nwQ&?K|fgs-6_oLqf|yQ8_iD+{m=KWgi|OU&@6cznJ`NKC+#`I zHaJ{0%(4Yy=`I>^{|p4M0b~?o_(~JWANpXKZBL0Xo0QgePfhJQUCAPO{|4P9_gwqg zAb;wCf4V)*q(g7bai_jBA+*by|4=*a>%{eockYCn3;!h`nJggg*_o#&8m30_?L>Pw z8mufpGM@C|%uFvOh$%EA`j}S{)0{R`x{C3Kzh!QAtiuuu2}+hG%DTxlI`!!=|1Y1t z1VfU4FV{yZd>*T*x8ZY&7k8OT4Hx_7J?{Gz^M@f&`v$BR*x8c|XQ9h-6(AYNUUP_m zHbWA2mwUZw?!gXIdC#jBMU}+LnV1Q)I@_EO&}J|Z#kGdEU_pDz)!A7Ryj9m7{T474 zJ4G^gr-6_>+o?f~zj{~3F#Fwxgcjo%X&ps~S3+Qf<=v7==oELlNf}vb=)5rZvs^NB zxjd2)CD@q{@~^5k^lPoAWkjX=BXOyP6$CPkQzW=!G49{6vWhI9!Q_dCG@eB&+`E^WL2SmB3B#ef1fyWE%f=#k|AvMT<=bk$GR ztu=;dvngIaNbnHq2(c~9W%5j(2ksYN2|HnL0r_-+^>1XCab?s#O=4f44OKYi$i01Xc^~?8 zxZ$d-!svUA;%>ej(J`dGhj?ItNx>aFdf%V$WrrM>~dZ5O8iu= zT|blg+sT9hV{0q-O7k8My2GU*=fRAybeTMab+!9Cc$0g}n$!8~lolVAO_4YVtFU|` zTonCr-F3So?FaT!b3;-3G9trd&CVOLTN1Va0% zi3OPE6`O|D!_ozvQ@_Z>YgYv+aQn8*9nylsNgVTHoSLvJNxpNv_PB+~4yXLa-L=i9_u!_Hr3m zTXpi3hrh0*B^n?JA4{@NDKREFlCk;}Z&x0HHisk$MmOsHE^^-xFER+;ko0@l-$B0* zmQOnnkE|k@OpR_zZh?w*ZyGfj24o^y!F*&HrDLZ(s>yV+)sIev6cYPu0R96L4ky9I zD>C4GfJ?rC%Fa?k0|QclACZs(qwhLfDq;((n%`w!W|L`?;w?6yNxLClBL`^x1DR>z zBARIFlWO5g+Js^}G|$?9(nlkro5by#hmuStLUK4jHne%fg7f<^wEwxO@ref>nU&i( zh@aWMN<;lja+_^y*@G?N7Q)ci1efS2>HF*+Vip89@g+@xl(p zlcD_Pg9(YXO}E$@b63`)z)Z}_>8D_K(ndAe<28nG75BlSF{V6s;qpMpYMRK?&w9#A z&ER$gbl}1nr)WRGZdvYz$U^O{60RskGNaFH^#$_~l>v7^qyYQ5a*M!c<^~~Q*%VY6 z5|#P8($8fKad$LFSD#eq?x+h{Ke7V6Z->ccIC!AeARWB^{GGrI6R=cU^HJA!U7Y41 zD&}|oQyT%KpHnwJ zW%Ug(dxtGBmH&Q1di9r`A$My`H!C!f&CYPJ$Q)zU@8c38S zK|1sFJQVgt010Ck%ZE89p`8ouc>VA@S-{DXkl+4XXimZAVN{-0@^`Uusn_$ISWGOf z$WOw;R(*tpY3Wn_NG_4nn)R78$*l2=X}j#g+~{raQ|OYgSrCsI%^5Xme3)9~BsNy# z1S3(1{S6wx3p;598zgIT>~IpQ#h3`j56g!ONyPV9rBS;hvlnF^@z3Sry5-AevJE=} zT@F(wi~_MTV4E%P{J4D9_0?J|GzCLkxz|7{ikALw^|1)5ir7^t>4cek_oU>*1wWtUCEHEl0WAFFH<-Ndqb3-Cu}vatg<816kUFb5;L-8|+~a$mVhFck`{ikht## zdm}=8TDMmN@}e)){`Mr*OYSF_DRslndr!S z*W2*;7?HE0?<2fyX`tGr`8F2w1X`gwuP&IFaJYIxtoX?I@(nj5ZwbQ`m`G9_L>%#D z$d$m^m-n(Lt>;&3)uFbgnE}|912*7j+tS4FXsNjWaRa{`5w%bLKyox>--o$nto8tX zkY9GO)_L78Z&{!=a?THQXCrytwPD%~534{TLZ&V;Ut7?h!(c0<7XFptos-NcMdL;e`odGte$)>%}gH-m=;7E5S%qBD_#c!!Id0Y(;o6ZCnO)4b^?JXex z$nyr#ev*`*L2sSo(xYe5Z_N3?uM_0El@SqF>NFp{(~WKo>d!RExxNrqTDV>bu?Y+) zj*9E6VW-KOb4S6*^TWumE9}7`8{1}POY%iKB?9l{e02bcMqT~_sM}d4w~ve8%*{gt z)e;tsnjRF4r6(v4Az@$8z_36Zu1oPTeF1zWQ>L_5!dZWRPTA z*|Ul7dXWEE!~)||V`{C0(9gmA?hbVT|9gu|8?nCpt*+ur3N%y`uK2Yc)-Zarh1l32 z;VN2_{^P||D^w86dcJ~ttU#7D=yh;i=gxL=B?xRItzQbRcNfbc*Vkw|(k-X&e0nw3 z)DC zk5^V4&Qg09sA)69HsTg9N3U~9tC`F8z}a``kyAFm7{+Wk6V5kD)b%>%?|c+KT%lW=cz`pUw2`dBew`cko{0WC42u?xaH&My}8eN55DZjOCBL19cEoLyB_jmYDhFAq9 z_OWUr2*TOESG&Iu3Oego9f~WP)3?{6Bvr!^u^{mMK%s@pRmJ5ru&2dMG{2FImc4hk zbbtnBG7!Woec#mPX+2QX#t6v#?4=Y28*-U%QUkz5;s+iQz(dZ;? zunX1pxrw3k5i4#lOE^S6?}ZWDje^w@J6ms)yeoX6nx44Rchol=W5K*jynRvj+#|nH z<1bq+L|fwqXX!Y_%UK_V5X?H_j7KHUGla++42W`C~Jn zm%@$(+e*(<0WrkaX!~E+3&$^t_qRJ^7C&hg=j#}#>TV48>iZjUOTeH^4%j=K5Gqa3 z=inO{3Vu}sYC$nK0}TeNziq8%uew+g9CQyTrL_t@D>}AZ%W}#P#d)|I>Mx3QSle$k zhF8L0lhI<>e9!Y9)`1cJZC_zKHBk>Oc*T_E%=F;Ux0Z9hB&|KksU4< zsY)D`f6v$E=O?cY?=t?!%1YW(bal*E(JRrH;Bt+juAJ@cG|1zM26$`YXFHQQkGGQ5 z3Vq#6>1CnWeDJvubr)OC*2XS5q-cvHXZ5fpR0xGWDJm&Ut=M^7Bi^a*^JgqxU{Pp6?lA&wlp9|&fNWAqH(*!fN3ss zjVj-gTVfqPOP}^79v|060|dJV^mRDm1s!$`^{}#U0!g#;5`r#GZF}$_+vh|$1|k|1 z9jpx0RQpi?urly2GLZca0rx2V$6c`i_=)y9l(l{k6BwH<7E0^eVfFKucwHtyhZE}Y zs9t+D4lQ!c4yPG2&n0%USXx;Bm?-E+?q8TCcgOI`X%Y9 zl6hUJ@~ILmVt6$Gb$dL}l-W?>U;0kE6`%iS)^s(;mQ>6luylY@R*8?tyIm`$`&-%{ z^wypDosRKc6%C8svabd_I(k;%1MsDBAu-7IuX~hBG%U8ZZS}uejd{9PnRiiCjRz+I zU9VE&!Pg!PT}iOQqNujE$krD<-(h?r274S{LnXvwZ=G*u8%%0O6G|4AHV{2km2>v* zVfESkc0DcYs@Sbiu#*t~6(Pu6oSXYHk|2@~dTqtBCvDFk?&@IoX&pjH&AWXK;fh)B zpYp3J8Q~5lR4on|a$?acpiM5O+4~_@1*jOM4)t3cTBS~EAS@RMoM!e94p2LF>}%zNveiBk-87L&rML;d-;Z96 zp|0rp^o^(@Y4o%2{}t2(6=ZvoY64jC>e`t{K}Lf?OZ@{GFmY;Jh&}!tHZci|zX+0P zZ&vzy=zQ6RU9mM?F}c(2&wFlPdY68!9-HEObGTe1$A{6Z0_n45_#f;ys8ujxN|~5~ zFQa*%s%lU3?&fVa1Ts!hi8<4DN-Zysq{*}BdA3W=210^e3~bD z+7W+N=MnuQaO%@CG_}O}Gv!)XE;%c@Sp?qqk0O{)7l8R(9&es(l*#O!upl_*e{y5QAZAz~ByAiR^xDZ^_5q4f`{|&mnqMVZW>+6^y+X;a23`jruKl~t zQq56wKuN&&3XIyMGI$-!pJqa>EqAA0_(lp@-Ri~eBo)PIu}(xv`TwQ`a6U< z+w5~n%W?H%h@Xc6EYfbhKRpG$e;rOXM8o1Z4TVk>T{EaNq@v_$)Pqi^yOs%H?8-$q z^WJP;c2HRkYKG-0$z}mNlk>|~rD64j znlbwSN$4AqxUhj=&A%LSC`hH7^FiwFlfBV>acVM9;~>?Z*)K@@o*qqYc$|%Hni!y_ zP%OE9lcK*WlJ&))E-ir%$ucU|d&wJiC;RU*WYt3PvIJqBZJ4~CY+1aYQ#qO$2cE0tsD2U<9m$T+h5t=Qc}Qn+OadGQj^^=sVX>( zmI}lXF0SnEn)}nZDN3H>WfEP=HHv-z<=gPl+>&lNyDEBKTU8B{Q z_3=I@L;MPD0@g5 zo-A#}n(3rc+u3$wb#5~I`orty*b|RyT~l5or}ov~+LYY>LE#wBSKr6o_xz7^anH9j z8`pHZFIRVcRSLqBg`M%S#ZjX$<>z2K=?C@S3~}s&Zqndn3H<#D7P@Kmx!nENUPG0f zMF>E)$TCxB5!+;o5?60FZz&^zJ|f>Kuh-|v`yLehm%6WWobMB=+Sc(58Uiw5;lhN> zqP{K-IQ+J3+|O7OQLfSW+;L7<)fGdc>Lv<%+)dq{Q};XUf%2o0X!O$gVkLpxTKiY< zL4x2wNn#!&U^qPn99n88B-e77du-Dk0B}fUzyD#nDPI{m3&XFwO8GTZJ3*f=QJr%& zauBeJmy(U6x7q`p%~I86G&2A3?Z;M03GIc=3`irNIy9jUC z>zwhZ%d;OO^P|%PI?FPPP<6($VEuu$?PQ?gkg|wr3!W?`52?js2{?9|nVRpP%|~_? z-g^^)jGucu*KZ@f8qZWcb3WS^uo*<7#aiG4!pC(TllzzpIyF^{P4{P$PRJPv(^+xr z7mZ3hOd2I44P(&irOTfYnNXCzMl!^m7kzB%id~gV#xXdTnKFV4D25}D4SUx2SMq5< zJlfKRRdStrj^h49l9*NrMShxV_EDX7iT#LBT~@|_)E!PTNQ*L)JJ2YDAW^%ncMLzM`TR%^E=6s$$ZmH?C@3*_M z*U0EkRB6`c=`W$_4+5)wRduxF1Se^f-erI}3&~vVyOJxsX|^vyje631WIRPvCOJP4 zyp#6ZEwtd_Fcv8m@R`5P7*nG%Dw&*ZO#rW96{V?Cb1Lb&iJaj@FNyg%+FT0uC*C1; zLieN%pKt@8%pk@P1k?)tV@SjdLdydn;V61(Fua_5(h5FIH?XIQu7w3GVL{yN{sqtSvU_1433X>fqZ&qqw_l_`k?;72V5%Q?B9|@Jnnt0 zOW%6F>x$kANu|JdU+I{VD96Gh6qBR7(xgi*=ybWq@$fy>GgVQN`Cg{FKXr(y!ZM)9 zr)A&YrK2$ff`V1CAczH)3yc-U6a+_?1d|Darm2lpc$PlVU}*j5`NDf2Da1Bb?Q*xj zJqr~j!P4oo1aZj!pp;CM;;J(xqiU=malqjh%!SNDG1uT`X|^29F0GLNL7>#Hmqf6T z%sx3Uq!&ND9B)sy%b{|p3R<-NdXQMKQLzpE+6=MYn|(hvg@+GyAc`{BD-yyH%90S^ zwim-SsxYnH$YUX+FMXG)d%9P|P#K!TSaA2{Ad|7!1!8Q_1i~_Umsk@PC@_tPF61-( z;+RNg8rsd9c+4n2m`Q$0h#WD|q!T=^XWeIrWGNRd-xmNgm^ps?daW2jgeDXOf20OI zh>JQkp^W1K$Q$CLqf#Q!SW*1t1;MA*kSA~NiR^2hSY4*>OJHbnwo`2$g;5e#$shHP zA<{Al!Da_Z9sOZB8+^U3+19F>@dBDznl;W4_KPBy*yo}YY*4jwi^}`k!BiOg;=6L1 zLk0RAmlfJ%;lZ%dk9&PDym=20W_$k(?y}RpnQzGt4zBoI2<^~y_0i?sbNo(T>n3{6 z@9X;gya`y$;FGiVPnFY^A?OZm_ZLb`Eq8i=o1>ZkU8eL=yE39Q>S57+H5_9I4cyvM zK*l6yk0o1ajCtL-aeo~PdYTJbyd8h5Hh)|zniV-C-Sy9yz(wkYT(1pS-UyhA&i4Bs zK+m!hI4&b%h5s5mKy=N2P?LrB^FLOK26k6;z@jrq ziiI#Q_NASsGd`kF6OPMRnZEWiY+hD>PT!13JE?e)aWsSv7$y589onwX2iCs z$SKJj>#gVA(<`kfzOS_&7>(p%$8{+4qxm;Y~KMWWyD0Rd^_;btxm; zvW%Dz?%Er!cn#yXfVrSV^!T5+yXfc85%?Gfe0|ILoJ}hntPu=6J^1;JrD*ilz zrVF8jTiqXwwzzA*b8VJx>e-Q+s|c}_fVd(T5>bdH&_s6pcXt5=p6TMqVhwPrgTcH7 zIweF`oA#_*`>m37bw_8n)lg+Am;FKyg%Law_vsp+XcX5WGg{aS!?*A$Cdq)>a!iHU za*li+R0v3LP0UXR_EX*SOG}b!7R+&at#p<0_kST*_Zu!-KYzN-B#+p3I;}OSJ!yNo ztE;Pb(-kwh*3N9+_L!v1Ihlc@@Hwc3tm8=1prHXq-|9!*8Y}Q!X~! z2Mc!K-BWyS@!MNr!o4u)hAoc1u&(gYXZ78~gEv79M*lUZEl^)70AmG2(RTmR5aklr z#^%hM>9XojWq_7-9+OX7jQN&GD@t)GpbQZ2$P$dK^c3{iJSxtCsqog0gWc48nMFSH zlgL`0!FWE7cFpXPHWj&{Rw@dI{;ww|<#)71j`~QC9 z<9FglVu{>L$lf5(DZXM2=7v5?IG$%%sn|s@UU3-JQc^;BYp=gHyRMIOCLH_jpPw^( zy7c$K{=^J)e3Xd=lH0 zZVXEV0C=is8az74;{qNm;MPpL1bYlWmI#DK=ztL1hjm`!I&Zf4Zor zCgR6rKXz=QY`w%xg{LAcsIi+wI63$j@~7y1%UFlHV+c@K!#3a}zYk0^50PWcgB)tw z|H-g!*g@Yx^$7X5rwk46w6jfpq%LBy{z8)L5pD}+RoExrlRn-Z_gIPNv_RgBXYg2O zDmg`3!=r+)z9CP-)9;Yg-Ig#fDiNO2*SAY{{DZDLQ#P`Z!ydX_{1c?K3AopiQH*wS zc0^Wgv$p4c(dv)3=%t2$m9-9*g{@T12BXdn*sjr0N5RkY?h-cAV!@veM&GZjHoZM@ zsasDMp;G02rSv_`|@vTbof|1j0KZovywh!$r zi*pg3{3r+uy=u|#UTcU--8#yIV68W;zq?>j%Ey9p4N2xjfUOrE;nVa@uz;>tn|=Zc zGiL08GC>YusdbhdZ_Yfi7eiF0r$|9%JZ_^gv!)Z!<;*c_hKYHfY8BBfIfgZ6pm#JB z$M@=f?%iaegX%E4A>1L=ou?iv5ZkNrAE{LqZ@r60u3!YK&YEyEw%$KS(%=+{v(C`d z(JLBIK(fET_VdV4IHtRF0%}7QU&CXJusb+dK+vCOTvok!aHr!!G{&aNaP3MndQ zm8ZLUjn%QcbBj~VZKPhmDOaDPEgXg-eR2C;FfeK??r#J;BEeQL1=G@#!w(H>8sG3y zLy>b$7YE^!GsF&CoTJwMys8*bm=N`>91a)g+m8BmoR&$@`n5^q?YXjY&Bw>l`mb|~j^WbEwq@c3;Ed*jRwprT2_?+fc1g^Xta^f@4v#1PhJ5`w3_&~)65YJ4yiBD}BvBsU``LZ__4@7p zQeL^n!wz^v1*CSm{`$4^ZU@%C_~t}4RB8*4&F8GVu9EFM4Z^K99Xp_wvFztyf}ap7 zxV^u5p7zPo0RmrXJyokfp!Z^n*M>8Ijp&2S>9ywYnv6EezColc8Dk!!7=ymT*eeCb z@PiKMnFcsIM&+@u_?MfR;i+VM+&UQo-=5z-B0hNqJr&(?I1;9pUz8zpO($F4$I1Yh zYmLPxM~l=Z5XvijUS=u3Ea6%9^qz*k&=r#=^B!-2UiD_b;Zo|B&4A#j|OU# zD{Yp2u-hc|1lJSBo!N?4?LxMQXWQXoiizVy#pQWfx0jfFq@+z9G}SdOsapJglD++j z3a?4#a9NK+AFQNm`jIJ$9gSF`4xuqS?+9yiVSJrgN0v4UL(>_AhbeJH%CNUH=)-bt zVaZR^^}g(n{dIF4+RWDt0_LFwG~<#kXzrxHHxLtc6@M%0TAYTJrwdc76Mx%XBl2Qd z|Icu*4!?7sv9=-rbvT5c%DOuMP_(@NLH`|c=x6vZr5!HJ6JRXdjPGZF`=OkmpPHT- zgSYs%V9HT1vOYOcT>6)23s&Lk%iMZj6XzrZ%~_v&phQ}hHN1woMuu);Cg?UG&5V!3RQ0NrTDH0c(Eo zo`}`j4-T*yk=?x|V>hBbKFo>n)Q>8=MU*wFFdL)qkLTvzD^fX* zaZhUb3^g`SY#M%zTpm25^O2+Da3%-u zDKtk<0uPmPolQO>@N=l~^4%zpO7>rBEe<(|@J7EO)*ISCQp~+U<;aIYgUFP{uK#?W z?+kE=2xwvCxjlnJgL8`psyd_{6QiiX$(2T3I9~mK2$|0s_ilDzu*C2$1@HNH^~0Bs zLQ}dtT&-$?JKjs|JKJZxCzWev6+#X(cfL zMYM2nlq}78Bn{L{H%d8xMG}2xfe-Z+j&53;LkU=EdK}fPdH@Dg`OhTG%w=%@Dt$M# zfqhxg=y4ReqJbM*&ubOjJhNrG=&^kfgL0q+q?`F(^*8ilX3VSh$5sYFBlMb{VtYue zavP+`CksYCUryfoiEz`Ed4$q5I69o50g3Un3Jh)~gCG6U;izL@1;4FomhoCE%_wsd zORVl0%&nvZP3NCuW`2nJP3e*ByCO&DYE`M8)(RE$#|;WoPEY2ZR`LyQk~o62k?6Ex z)ddEhd$idHw5HNcoYhCs_b}nKN~qE^mQeA^}6{zMlanL0hh^or*VPx z5rHhZhq>-9(QTpE#ZPg+QZCK)yajv?fOVtgsQF|PxU``_FcFWpV@<bBy%=O|E;-Rd}C>>k&6GU!P|1Fz;u(-C9WG2k*YeUDgdcbY7w zQ(|eYkUav=@TTas!z!X<2rjhoKl;NX83a5ZH@Wj{1i_c2{A9O#wf~vkYcx(b0&v#a zO0KnHt~y?^&x-3z%s_LI>qEnq#1v33nJ?rbXSx1T@B|Hy*v0qzHryvaq5CGWkOQb` zw`AmQHoRB*yZ9rYF>4X3GD_*mCY#`5f(y;XlEum=jfYhWS)`TH*eb48P2Gm_OOL1y z=WTz@p<=F5<|Yf>>HR#q*iC>R4vCR*!xplH7;`v5upC_P|zfyEfcIHnOXgN zBRJTqTGBN;dD|fY1gCBissI4(A5R%|^;Msdh&tO(?@QP@#$&%vikDyEU8%+xFc|5- z@$h_I4x1Yo$VL}a>j34Ds`CKYgM4F-eJ$E_w)rBC;PUO$oId5!;ZFA@m8k-z6z^~V zEw1SZC6M$bLZj_5C(U0+ZK7+aVl_=v%)L$Ts6P|eRj-=`27|wiXRjZf*e@E}Tlqip zLi2^tKp^C}1lY6U_R6^r3v|nMm-|Mfo(J09H2M<*|H)B^sTEG-A4h7sbNX^F|5FAm z9tYUkF+~i>6KZ_c@4gc!-P>cInI_A-h+VUd2gA`Yf@{n5N{YyBp>ewuWqo3z6!kQV z)W4)fn<4ca=^fDUejW%&kD=Cwjhn)K6O8{gperg$W(zJ-Ha|Dr2tcsLS8%*`G z?(U?8wI;<|8A3h_cQmSJMVn|R*+PU@cczL5Sx}6fWr~%ROz5?G*?H@)_j&kDCYY|e zLyRL>Aqx`eA?oX+L)OghO?js}y3bh3Sa_x_?R(%1W^m(W@vTJP8Wp;JKt z4VVQ-V)x$z$q7}d6Gm*WBfLTJMD&x7T=i+bn|OSkVGQ>+#rmwIOJ`!(pPZ}VoQr&IpjdA5Uz7YIv|-juua7g$~-*{x4&QBbs5`xw4F<K){X{Z|1r^VG+WR{&rd_-GVTUY@68R@gTFc`*Z@(n`MbD9M< z?$;e%gkt|zYpt&ZQ5xFGOxzvBO_WN+a_{CWZ4@>wN>fB2(+EaHNwY?!CGdylum@_H zP$2mW(;UjfB*giRW_+=r-z`3-SqyfT19>IZ^p8Ur!``Vc-r!tGvO5JHBw&*X>a}mC zh?wxEF_I(7E+NTMerB}7OU8y%q<^#a@UfLCC;&?E)Q7DW$C4>W6j6~bNMteu@3*oF zSXd7hZ8UPoZ{Sdfnl!{jTGfuITDTYMQ_HK0AtmTDS_w5e$%s!f{6qZDvH<@dO~UYC z*cwXgACFdBTWb(>1dL(q(tqhqnDR!hByzJpI*-iOm^F#X76;A}d6!6z&h*g2lZTU{ zxw~mL3IB%Z;le_{yH%DN%HR^y@VMKi=P0B!A_OJ1Ajrb;RJyRG$qgxtKIHVN(LHG zu3oj|2IN{F9Yf!FZtqbaQe047A)60L6hE4J(lr_RGrsa zJ|eBaSok&5M2xn9E5;&NRQ!u;7GH^nk28%EnwWW_UzN4PkOt-z=a2Yj$w~h-Ilnn5al>=9# zl8KgFDk^gMdsVIx6tE=KOCam;&JW_f%hL;J{-xid4jsbKslpm!b{_t9Y0I4^kDk`C z9Ml|ntxbE{MfBDtT;y)V~9W6tbaNE*1+MJ1z2w0mskn;Koy(762x%;u1a(w|AA6L zRc*wDZPU;sS`?*CE}^!F*bMKUNRa~YkJUP;iB;1fP3U>9RtFUlb75stl*aw!OOQkR zoua7aaDD@i2vTSqjG2~vEJxb)^maN2tGjN2brD*qaD!<2DRW17Ebxxlu0v_cAM8tO z8E4vk&njvdFDVJVhcU%|+#D#ZFqAw8z{3 zw!*yYW0y^Fg4gZ30)-} zXrKH=4x?-pl3%Oim3)P%i)^CZs)pZ|whzmg1=P5F(Y6Qby zLq`k)V+kH|KvL$jFeAFAcwgi%Sm^KDIp#YQU!=lrU<#N^aAd zSD6&4rPsYfPO+sCWB}|N+Ab{=xnU&g!cj2!1OdE4L!pu;ouE&xIoau{QeE z|C_t9-mupV5}C>UrkSfd>eUy?Q-^j1BgQIxr8jzKxN=_iG_o$Ble-PYl{dnmc>4Rw zVV|^qqgEKPHW6;zG>;(h>~xuJL@3qP7J0TBP5ED`A^5=pHxyL^CP*i-T2Pvd@b#oM zi++pjEGL`uGFyZ|X#`xVjQAJO(#2yitGaaelRY}hg2JUW{ZsSq042Ls4X)ek@zor} z+F#)VHq6%zr(1;?tB}H5#b8~aV!~gd^#sYkuV?+A9mY9J+3Zgb-QFg`S_O#_aO+`e z?Gh#=G;NU4h-oQbybb11Xj%TXCux%t$R*2}ED*p@T4_mvnBv(FQz=l(iMZ4*nUvf8 zyGffq{08@$IID-;U%&CR&c^PSx&On|IWS4uHDP+%sA+4aZQHhO+qP}nw%yYVv!z`l0PZ+EwWT8gs%Tv^p$2W6cCaQXa<`rh}wFp7Vwl>i!>x{Qo0Ia_W!Xdvdnx z&$=J=O%Uq8?cuSkK><*BI>1_8N^WDW-IgB>yjXoZ0bh z?)ZM(g38$0;#pW@=`dGh1~=DG^f0cgJ**M=rsXM#r^_$x@BJmMh zpvkyqilyebp%=3XXGZjArr0N$W3NpB2J-jI-)L85O*QY$EK^b(%Ym*{n>4x2Y{*-l zXVBuQD|MWt8=Q~gmq7pKhC=N78w4z`duMj1 z`;}c5U>j8h6)0y1x>be$+^QHC>!xZve*t(O@hMaxA@m=iAX76`1(@pb*-eIyw;Cu< z-Hn&c@3Zp_&;7oGD%I>~?~6Y|ziv=Z$c<4n=kUNWGzPUGF{MnG0AmWU0MH}Ff4Sx9 z$t08(Ex#RlP#u#6Q5KRg&zLLj5*D{@w%+s3QL)vjopU_R*IwT`zt{ z`l%fei*4@yS}KCAG}l#ZF=+SHk~hvuX2B%uH4o}mupGXbe1JmO9PjTu6b*p`#iZ&} z-WCn+Y_La>H6`;cg^s>`CnFG%FTkN#IO2WiHYw4ejfnmxy)HozRuD_W6(`;yS2|Q1 z9`$ncfb8*70pzETd+qW$~Cg&d?MA z+?c4tmPx|~%cI&awL_8qf1B~`v;q5`OWM5`_I?7O4+@~JX$lPmV^b4yz3U6rx&BIJ zGEnHbZ&+YKz3QU_0~oE@kva0*;#zSLv>+hkk*J4)@`Zt%{Z{C^>OI~RF_ga>vS~n@ zfg{}R>f#jTl$P+51@oyQK%Fz1!)j|y=l4!pES{8;rv7ugnEJ$sgg^E-|I?{2{7-A{ zm&3q*F|McYKSd`WJ`>Y;(d_Xy8j?yj+IEDsB;zDy7IWq+79&KMHE4=8IfaVcJ;CC& z!F48-&-A>BxbF2XH$gU}TeDs!Cx0e7Fg39zU(!L%`lCTH{X{@cqH91CjOjVkrM0NfO8yerS0QC$uyZy_@uAlt8u6nIO!UlwBjD zL3@JUq|jg|+C@cVn-YwNhj43pN)c*K^0rVK|^2%PMmLQW8e1t{bj`)v{L% zeak?(IW{6&B2>}-jnaL)QQm;5-rmCk~aUty8cg0oDJl> z9Dp8`JU2BC6~SO0S$#38-87^qC%9qAv{fJ4$i-jh))kOE(cVXS2$Fuu& z^hWeO{G7R1u3+d243B3^p^}Wo@jy5SrKybyqJq9&x+y(TA~Ofw#}m1PFh}q*FTM4s zFXX6*8A&dKh(tVgq8TZz06ekotR*#lGj%>S9zMXvzg{xK%+J8~E7ij_OQT!BTbRwZ zP##(U6llO=|Ft>udf?qSCrEaE&#KxGw4P=gYiz1Qv(RxcjPi5S$XGe5jKd}Mb@*#i z{m1(Tx^ko9E(Qhy@|>9eDoTd{MF+{1qWL<;b6NJNI78>?xh;k$<-D>Oe@A;k0FAq0 zY*mUD8YHci6SYvPmtNIgXH}tUT^6Hs8ox$N+pfEzT6gNpZ*ofjYSQxQ_aTmWMw4-)6)tfhwi-_Vq$x1@`nk$-|%^>kGT@|6@Sc4M|!b%tEMGtVBg1; zDF!X*hKbH{Jv{iG0!_!7;?qD8k^fD(*2V4zs)!6ILqML zWkRC!n-@UajY*r4)FLLA?nH#oR;(i8aM8)zjz|~QZMR=39y;7Kd-kaQ%QJlc>%+Y+ z?d;i_HG)4r_hxdLo7-LaUWB~&_~8K#Q*(Xl-!FqeWxzo+ZOMPC#v%O`*uO^-0Tq+% ztd9@6blcflex8L<2dL#fbBienSBgA}Euw-bI5_MX9R#w4c0p z49{Pz&Xh?8T?Ko;zQo*IUf;~oefUbfR%=loZ%~$;^vCD_88pC%(-}cYI<&+(D9W3W z;8R5B+iZ6_HaJD)gM zgpJ{_d2p}1%ei~;b?`gY8NxafbD@9dc$E6|+!3i{-cD^=90?5?E29CXf2NC zbQEdGYXslvixCmWBU>pr+N~RJY?f~cqV7bBwl|porzxwAu-)C~`UbBmoCojOSZKX$ zoCXIVlYTc!;R^%}i9{!$f=k0fM?)mya&fktkU>3dGMHnc*8=l>lNDWw8}SkXWf~Aq zk>QP>5EWa#rsZGqHh+=h`;ld!uk9v-xwA+X^rR0)j5@M=1^GEVZfz_^`m09c66=x` zv$Tyjk_KBzG1@0>7K#(FDI5lOFkMkh+IOM+xPTM25!GNx_yKEFKp16aw-b^I1*1$F zaEvC!`Zah`kMi_+ljXX(K3bZ|gYi=ox0rz*Swx^Oy`1IOA3~n2D&2$NkvTb5&+Cpz-8523ZOQRPq2$QP$^w}UrAOk_VQu-T!I!tStg`9qpHDE{ zA~rT0dT@^5p^Jr>nU4YM>}wm6zk{FdX{1CESX*+^HQ#fG zOKojKn*$Fii({_>mc`B0VCEtJ_?IR&-$@>yir&SjgCZG`4|N7shUOCx|J!u8M#W`xc zkYaoCIV=5?YkKZ-1YT$`IGTfHzeUYOf5S)^1t%iu@SZ8;HtC1LgR0ui9VdsuCp)_B z*I5{^T=nLUY78#bOEECya+82u^i-=a3&q^N8dW2t-+Gy4KMhqV3F*V!BF?PmD2P0M zl6GNp=+6|RxQNpeOocO)D;Hz5*!Cl>;Xk&(#cHpYRUDu4KU~vn{TOILVY1rEvfzW6 z8yyg9cVGY$q{uCtQ)O7R%!ntW$XJ|h9C7_LH$Ocyx;n{$N44g=X|nDnVD*40hjG34 zraZwv2--tK*dG5KjLZaF*xhh?mWn>gq}4={I-D?(be%$}SSVb3z@P9D*%Yp*9=o1y z9Y_){g_QtO<`i3{E5WkDDu0ZZg@x8|S0rZKzPq)Pb`+TAC+;l_T;}@UuO5g;=zju< z=qq`^cAU=A=W^6rkF(MD^9|Nvd8it^YqueJ3tVI+fhi4mkR(V8vNhW@WCr?C2|cCl zOLM?yulbgb+{OgomVb`@S_N0udaM9(hoWkoqoreYX?Sr;ge7ZXr8ti-Qib9u@f@9* zQj&Mfr5*c+ppw#ixqW?hvCOrvzrCZ;yyBNStVHBJNk-+tlw+|0HHP#v-)#5uoJh8O z?|tNf6kTDwj(WJX@x!kz%oK6!59O2uyV-n+IGo=buUkd$xW8;q&9#7{@>rXAPa)u% z6;96uyH};7F-~?b4rm z|AlXl|ISbje~(dIzeoHBf+9NlQ`ZgL%;(e2O9mcfGJRxSi)l z_4R&w`Jtjf{n$M3ET;41S2=K zV9!~o|_^u5snbN6% zGg!p*GsN|`hb(1&&)-WSA#y%7NL&QVf*~QQ7?G}NNEP|^`CjVEx&iToCqjA!&`cC&R?~`*2ALG@bgdduaW^{)9*0j5DUQ1p zDK=Mq+~`wbj>gIqy@X|3rSc#rgrh7_N3KPxnm=jB;(8agUa9amI(_IYR@=Ve-8PG_ z3$}!k@8I_^*$@nIMk39nf)?$X7z;u(vE9ytr=$9icylg(_Z9Wp_WRRSnftS~cb#98 z)S7ekU;C9F$~yE9i*dtvZ<3x5Vv1ROiY!U;_NK(UrP=#S8)Jgz+ODjoNkA%t>3kTH z;EidLKEWDB%2pL$u+m1pfMy17GLvrCpnb~#T*%VE$6%(T94sIX`@ic-Px@nk9`-*e z#ZTa-9k#srZ@Jd%*X1kfB(0A~p$T0M@*gq!1$itN5e{;@D19(0LHa~M1*n=%L+?d& z5#4vb)5+k)GjFH&6vPa3Yiu~7Q2{zc@ah0>*%mY&ZS|j$n?aHZQz`UOYEp>ZtDdTq zBr@u_L_Hxo=Btj9&(m7S5^=V;GY2Hle}!BPDG4~e0%hnM!Zi~6ny!!X3)5U)2shfR zi!84DP|vM3Sj{4%!H^>wnW11bssdgu!S!T1iqyH%a5vIdA787pPQPQ5S6?vlV1fGo zN~L!iFvWKV%L@wND=AvIk?xPEiowa8DgHS>3R_I@{IYgqO3X>;#{|Zh*>D{hL4Wz6 zcrpw@qw%-|^O)dEfa(L+vey zfsTs|UyeGvPNxxrp)(+VWoKNxzWg)qehet~HF#%g&87eV z2y9$km=tOyVX#ag|6cG@yZ92*V)r(@D>di_`Nkq&?JZ%k`qktyWkUo?)o-CdqM1^a zh(U9AL(VDN5owE;-| z=E0szvDURz{Vq36>Ljv6=+YBZO4}Fg?88^oL7j7=1 z`of(3A5oPb0eZ;#SS~VV8u7j~exWD{wyXvtQ*UNjSH4wZ>0i$<-ky9s5Y*bwVZF-^ z*A+hB@54B)Y`EKVe=bx0qZ=D0j^sUoq15_~ux;I_E+e+wL4wl*11-%XPqsFA?)ETZ zO4J+`z3;_axHck~B<0vM&tLxkZY3ADFUpQ-dzOPF|e33j}wn>ysr9!8WDFq?``fclg1Cw zg~kjN{_fyTc=N)fr|*&^CHxP;X`uHXTF7aZs6?+&P9{%)}3gA|3N|Pcwn*L zSdb=&6$Gvf`q9Qp%X|=X%pNu%cUqv_y|_7t>g8v@v!FMk+*bFnNHCop&WskdjS3Ds z3JMpq#)po#FR=dJ@u^?g!^P?LY4~s3%qul#eWg7#B&2Y`_{z~7wXh$WREXfucr-as z2`jp;*rDLsb_Zq;klHn1>eo5}>N2KLo<+P%EHsSp`(zPw2|#YWx0TEBjj_0?fop|rFZP^az;gZFBb3g9Tt8Eq z<6qb=b}+}*S^&P*>uAO)b;dKUjdt>OmYMY#`|7@^P`Uy>LLN3g9qk(Us9=)XoE*8j z!58EO4r|-36r1dRVwb+sJwcYU&EBij)${ZG=uwhq5uKQx116Zv)$txs5(HkV2YN=j zuxUIjHtB%PScZtcUPM6~%_EKh0_c?GAReX<5M@`?R5n?eA^`J1iq<6D5u9x@cfR6! zy53ptc;AlAL8#;6p6$6z<^|SBxMlI-e~8#)63>GqCwsuv94b4O<~jO1`W64^xgOKX zd7(t*E>#&iRzy{n+}|aH>L66J-%4Y=pH_P=@UK{eg(PAN1kDq_hI`O=B!^CTHZZdz zX3l|~rP*3S6|p|M=DL4gaMEq+Um#Ae&9?P9=UK)gWZ}4_1BVXBZUDH&8heYx%bU5p zpIb~Wm%^4~kPAR8`Llm6bJT8|Va$i$WBtlWmmHFBD^BRFFP$nyOy44%H=SX04&R|0 z{}?KZJV{C*{8Ym2gJqvKrY&^)L8$Qv>i%3Z70_dKoC+xYDTRfZ39uz1{tvJ&cK)ZG zdd7vl0w9yqf^3RqVLI`MN1@1)0=wL5-j|hSz!6sWct`A=x7Hg(rGf!I`4ns>0?9a+ z%H)OD!+}x-yOp!B&S~~}Kf96bunvw)Q0Y}4ML#fCK4|KFP;Z#Nc~Z^vUlyjI*fJOM zLe+xUJlYwa4VRNW)Bn5_^321Q)~k<+>6cVdER-_t4r1PO)jOW=NbvbxXEi*Z`kkY& znd62@U*sZGU=|4HO+SPnXdO2{UJ@SrmY2H`nhYCt?)sh5x}BVaHbA@M_IJ7%Z+ucX z{!Dz_Tba&5Hr^Nh07L;QBNq#FjCOqUEVQ<7udyo0dBzA2;=Zkp=juw?eAr!{!pO!b zQS(S)Mi+3VI2~d<(i|M&GsI9tOcd>l+Z{|9Go&R?-XT)LN>3MyAf)cpBzu&O8=xki zdo1Y@fRwL)r)2`78(qdMIgfZ&pW8*&Y^tF4KV8q*e+zcTCg|;feR~3!awv?$1s?+qlxUyR+|&@Ek-dg4zPmhC`!&$UktAnn32vz?s&+9`j zTF~D0kkwb4P3u_c6w?Sr#3dy)UaOXc8s7rVT6TQKU(B1_%1Owdn?E+wI_0j@)@_Jj z#fjqGjosd--&dmHS=_Si-T#V!IZi^77>^Zn6It|ZM(qmjq3VopX+&M_8UfyIZ?N%X zU3xqR&*gNNH#^Jo3z1>k;##O#gy^!!dMrJsQOM>IElC0_S?1pH((WAhs48v5m<64S zl_!e7CU_jnI6Ry_*_adnE&~$6nz`lFMb!><@e&z7J1Sk#T$}p@t%@v&VG&`U4)@?i-Mt=8p zvjzOA>X;68Q>kEH%r7XOR|l2wha`mwLIP#_MIa~Mz`)8XyGc&P5b@fn_Kh>|S9ZpJ zcP`uM^$+&q=HIhr=Z0<$x}Pd~z)-ABggYW3espj>Lm~(ac(?#EW~Fkbl#qnV=T+kk z&rMIm_Q$o?Kb-E4n@y*u-`8$8UYt7{UU@t>$E}(h(=2dCT<{~XOT-JG`L#S9BrS}C zr0OxW>aTC_!1vAJqw~qEvwR(&#CEV2e0l%!GN@pRgyO?O&54voRi92O_T0TB5o zlSFkYyNDt=Asgto>wF`N-MoYQL=p z$(DVtR#SGLOg^A5%(hi_^))_g?ROv){$PYd?EJdUB35$i7eekj8@=YDV{m5Ae6Mw2 zdH`J?Woeo-AbNY~Rbo=;0B~lzE5PCQPjc#d2KKqCg66Z!LqvoMR8@GYJo zJO-c$8mz8!uzwbPCSedUhny{MCPGXQeJIJEsxo++0Ik7zpsqoo;_;Qwsd$ zuom{x%USw1b$e(lI9vJWs$&y?jj_sv1ESKhyR|-K9Ps`YE{D{{>oztkv`|O^}gUvy3k*kWl$||ec5%X)sZlRPa z6;&D#=G$mHni0*a*U36FccEx~0jcq=!*O3QsY9;!Emac!FWnyPqKCro<>b%qxc=K4 zT*8@TwRSIuU_g0s-9MY6#AUrE;`QZ~w-(jJ8Kh5tSl(|GI41Xz?)wZV%X3&~bOFEe8`E%3D>+m($6Y(H7(^i5} zK!NQbs3mrS9l@wl;2MUV%6N@n>y9zQg6Gi=))P`=b3!(Ab))OvcgNn!>sUpeHrP*7 z)I|KDg3Fo}M1ujP#eYBCq-$=gq9pgJFwqP<ytd#D; z1{dndJb9)$*epNGm|o7gtl4%T78dt)s<=muG!SL_EeCDu*_#-eqQGWTdT_6qUn+2| zO^K?Xp@hDA=shFIao;CHcw_*Y6vAXC57YBnu3^IbA(HQR!&V>1T9Z!h8tte*Y^`o> zHX;lvQnvjCtqO7>y&qtHkB1M(_oPfls%Libp#e#(&JLtrpeUp*8qLahYUMl*9h2ZA zh%afP7M8E_izqvB%%|?wfz{)g24v09S1ZmrkvWsDl`h5}e>I%u@CvJi*K(q(}DRd+c-lF)NeKq3Hdz1KQzgp{77+a`~81pFjjZ2@*a*HF3vf7W5)INO1j1c!*>s zWtt#h9z$PX-3LriDI5AU6}d9L@T~KmibN+M%)s7rKZjMAIvAot2@Tg7y%^Ee$+gDi zm^R7&ZEnFCq&GQ;+cIm{)qPhD0O`qvlxqJZg9ki>rN!cYLTC7?_*s}XzkcaW@=+oR z6rK&fui4b=g?F;(9EP*`FupYho4DyAvUE>E7wt-<*71~jj@hwi7JdjKbaZeE=3u_p zb^DRY)Rb?#7T0?CkQnk8-5KWBc^gS+Ct_~75 z=4RZ|A=0>6HPJV^C1inV6QUQd4Y2K7=lua-X+#QX%I%%BLovC{cWtnJ4q9T_NC!Nu})(P4t#Te5mMYbh|UU-+q;AM(#o0Mi`07wL{5+7e>WF5xjN_y+1d zPymtwIImJAfBnFFFa%&1eh;hL9loI=)BciZf6hzGgDsVwmsNuOSBU7oq#*ElY)lA@ zGz>_)v_&x%}1Dci;OZ`bZP5XDu;!F*i>uO+%W+#NZ9pq%DFnX4Sd zv5GUz%}P*>)!X=_XbGPu=SoIVM>q`E*l{`A3C${0H#vi zrI)&es~$fPj*4DPZgEi^M73B)_`J4KMCSfflF07Xx`d_)M=Q;w+oxlGs}ejgx`J%1 z3_D-T{es>onBqiJgJ$gX;UapObIhD8(Nj>{A@g~AJN zPmi2w_z$FVDDZNE>afls4&;D8`1IZiw7C-W6@MNxDw2YBKJNl9>?H!I29fk}4I6m1Kh^pm*f65(gCWS4to(U|E056%crzQ$b7f9bfYcK~tW(#g3Ui z!4S=N`^>uuPPd6!52$M}iyga~(IbXjmD@;UI`n1~tgOIwKYg?5eeyr3AQ)$Fm6Hc2 z-fs9&zq^iXHPFu@epv_#r8|0Ec9MKRmny3sJeucmzw&{)3CQ;!H8%>0Y72;BR1edf z{1V1ThmJ=a-eD0H8qll!a) zb@e5&Z1>0U`}bE}J(R^smlBg5@8-G#$gqp#UqS<1XGjnRz#1-jW|4JRt28K$wM93( zi?7`?8kCJqXi9R$0X~>7yK}+OXzn$Um-E9+1pxkF2^>qI*dLbD!F$F+qOHRz=K@Ah zQv26Jub1aH)|QOXMya1|MQHLVxogrd7iw>Xu;I{4n}w1Gy-yz3{l>N040XP)lgk5m0m&od2fzkuIsH&xBFs$YA0sO4n>D$J@VYBRH zGhASh6lZXzmPQ;PxxVQ0;XBp7yYlbC`K(YimJmfPk|_-A$ul>Y{;11U!%}Di=z2wU z01VmYG)b0VTh84WQIPOKi(r7M$eeSlM~yIk@UkOCwuD9Aq7>in|`u*XREyj$d{z+90xCxRZlTC zc-ZLfBpplXuehWZ&<*=RxwAANTc;yCdCSjlm;DPyWHsuu54$7zxQo*Xk=x2TtuUYb z{M&snWjZw@_oNrt1r(*aQ~Xab=1_9~dOkkOVmCYg<-h}&^X7Eyw?yHX(iLpdPsfk? z-gY_DV^9L&-oiujL)>P33|BT92@^+$bo}c zocWDe+_X?B{c|>xUwsR85Z9;R2K+j3l>>4_vJ>!z)M&COiaG~zMwjmPe|+sVfWn7_VwC#CyIE$)(YxERnMC?O{#dzva= z32B`e;B)Z&X-!EjPBzWW>ooSY+|u7jHjKB)0TpcjF~r1_=Do`MFPYVuQna3zndLw+ zhw)w#w1Kn{FpFceYqr{I1y88xtj%S%tY$kjcTPBB+AyU+B=TxH)8QX^PHl?~44H{{9uAo)2l8)hsuDMN9)X!I&-i{vGpoO3HZuqvGB$(;ijV28 zA>pafNBHq zeu8;;G-ihSde(S*8k^i-_RSIyQva~cp59jmCyHbPCY4uJ|!@CnlGp9P)8f;xM zmc3)0Ew_^E2=I*&UAK!_52?dPR*dL<(TXc=!jLhI*_xV?Qd=8N`=BF;kqWy76~{!%^|9J3kHs#;(+6y7&2Zn2w%8 zri>oq24Hp1RAX$@2jKCOW_JzB{r=R-<=WjTF z5s`dPi9`|6-wPtpBA})xodJb;R3HQgV8;8hR?E`b*HG^^2pHMUT>L~*`4xy=*_-!3 zxmeA>RWIPqj!Cwtw-Hm#c_O%pOe2O>_RHDqI?Xp3Qf3+<`tz2}$-t1)RrCbSuZ7VW zgF5?8aHY(+@fHUoA1nKhx&;<8whJtt2G+4Sj#G*g;r`!*70itWMBxe0DX{1du&J9X zl}r5(4RcVeNxpt{)NGVSPs2u8+m2#jRy*b3hOQUki@sz=T86-6*ad67tv~HAu4&fgY5M6yRbb9B8#+fAkJFr56qeoEL)C-T3J; zi*kwQ{s!b`dbsEwXB5m)OZBL|s30TwUY>(duZ8T+-DW1g_afV;5^Z?X!&Ens*#T5J zK6Z3Mm&wFZM{k%QCqXhWxWgV9#}_qVBIcUdxjM|DZzQ+Hah$CgR@-d_UZa1O2FF8O ztqAxB6Z|1m^%om}w?RJBRY)5i;;Q&|ShXJHh7la-X^qPZe9>zkLNxTAhOx;fyz9JdiS_L)EYP;O+0{g&zBDHy#|e z`9%*rdhv*J%#k=gx~?Rw0ea8$L_gceDHugrH(PJ6R z%~|`vdR{Tr%A^f`^2bAii(bGM$Wkp;iC>xHz=7Sws_d3yskX%c^VKYn-e4_;H`ylb za6ryM;Hfw7YUcmHT>vVH5TvNl2q$9D1;N6TFh6w+LCL@&n!`i5o}dMZ2J)K(kbB_Z zd#SrOOg>OES|-=<(7!;kxJ7uMP1?^`J@)Gsy-_#1^?Nh2oNUiESzqY2`1Y7p3f6F5 z8g7x;3NN%?DD@0O!36Tw`QP3TZ+gkRwr6>azK;A<1l6mG=O6?iek&HLviTn%2fXq7 zXN@n8`0P{vN2>Z@C2V4DFaF%u!%h{KG{R-upJ!@K<8ipTAIuqblEq#9!e)ET#-hh| zR%gTHc{(1d%^(|&>D~3+fTB}U4gJ_%YqOeQgR_?Hq6*Vhl-yA@E1>8b|2ob)96ND2NtfHg z@BOCeAEx~X3DUbfNZxN5)X<5h1OQ<(8R+FNu=x%2s{vMjXY%XQYDD>BDJe_Pgt zWsM3cXx5Zh^->v=TaD@O=bXy{dN?23ppSpwWGB<(m361Qg-mo6i${mo7&}rgmj_a% zLte>VsLRM8gtLgy%CbvjQ9vx4&7aNvdV% z{UieNxqAG+mNGHoV1kkVelZ6_Gu~uFhS9b>UT4j>)=7~%Prj{JUcaj~XM58Y{Fvl&A-x8Ikj*Np_H&M2oRZYOLaM23>JOcItN6ifT01_~~fC z&w0OK9J9)W9+*Un@(43BVAN@HJ>FqY4UQ%Z4dsNP-5`A3DZ^hSDTnXAYos5#dI7-| zSo#s;k)tEl%D*>#)k`iVBj}vq1n6feplBf#6y=& zy?C#8i?g4u?p6(Yv3pIIo?Z%&C%uB-+rfXYC3128Z%5?v@7nb4$xeG;6PYlL^Ut{)^o_IOAY3x{p#cT*un z*X!vwau}dALWcdJPZ=9-v-%+R9E50^KK`1-=q{K!GIsXKX>eOx4pE`CVo_xugK>Cg zdeN(oR{l34xnZ_aL8U2R`4z?S1Lr7M-2OXinu)=+fy3F$GLMk{)ANekbgUCl$!k;0 z{{S(C^CtQNzU^6b&r@7PcDQT6;iW1IH@XX95>Z1lKSz*6Ch3-@C_tS2?HJY+mlVdQ zhf7l6ib<+otBLQ0%CDmV6&teJif)YVAC^X#XUS zoXW-=0#W+Co;Ug-(htXw6tFwgT`;6Lo~ETdZ!G=8YuNkS58^s7KX4XqnQ|{H>^iU+ zG!N+OIK_bF%d{PSnH;!f)Q?nW%!c~?Ci@w@?^Yl%{k7xbdcO4e&Nh?V`_gy!_4GA} zvgg5mVU>5)^Nr%sZ+|Ytam&4lXtM8Z;i7f8u|Bh!uOke*CdDzuE-gvssd?$kWDaYC zJBqbDk|LgqZrGSnp{8aSEcgyCFp!#yA1uFCqg{$!(FMc9_XgH}O_`DCMjWfQ6Tj`- ztoqlRGTDBqW#=cfy*Cm1fX;1q-f0|3Jx}O-1+vAizpwf_qer-)O4~u2BtWe?fklrh z4#I*T`a6bNT`|;-COx#LUO}G}cEO*khuqD(V3@V=_R$mwJN=ic1};@9PAng7O3`>mdc<$fKhFyVb*vlr0)=6E>P1E4yH+f!TT6=e!Zc_8;XA6vl{ zO{E}ajyHg7nl}z0vAX!P9Yn58pk{)c1h>>L7f=*l2Z}-{X}`mES6ko5RVOW+B%{dw z%99}`AHij{>nhO{o`ednpNBDCBDC~JR~5w4`1qK?Q=<&eG2(~l-miVRCZxIBHOM1N zXE;gfgN#8p%*x=pp%XHPm4iOXVhQ-BAU^`j{^A&ME@C9?^%Y>{uDuRi@s+;*#OTN} zuR&gHu^hA8;cCtVA0Yw4-Jbt?3^(s1YbXJ2_&+qEuTTgtRTy=+Ieq}EKK2y$3G#vE7_?&pY@Xz&vw6vN)Fz^_ zDtmW+PLi@&S1IOuv_T6>gyT5w5wh1%)#J#t2bs-O?CfrXIqn5!I;83-WH4$!E_%rt zqTu|5b5x%&CLn>gS=hlJuPS{)pL0(y(^c~SM`6Bav;$8qF7;Ce331?C3{()hc!6*A zjAV=r$SLH$)pH=NZfMO3NF?obWP2EMkw6IPErH*L-Q1dsAq!6F&woTC-VbBImAR%v z{|yK$tOJe< zIEG^Lz1|mNQA<-&Jv&U+g*7_zN6mvzp|WQ^gX;9fIz15xb=t_wWGChhKn25-Z6r0- z#)2dE5)FhS!D(SXjYE=4h_r=|HX-P;Q+w20oV_<;=Q%4mICTq;i)L(;HQO%X+i&6` zfqximzfEYiQiB6E=4a|6JOZ=eVrwQlq2yQ9Az+R7cD9oe=SN_z{m*R@PMonre<|R^ zUpQX@_^sB9ToV_Bpv^+~_4qCmZR=BphY11zq*8>9cv-D;Rkd1?@#^lDAHRw9tjcPs z70k=#idYbW@6c_~Q?MuyY_@0rGFn-Gr0Zv`PC`0mJzK=gC^Ue}Y@y6R0d3YxF*Fi0 zArQ$$Mq2m^%tX)$I(gq2DzyDCL>|4Vc~Ozj5TrJ{Sbjbg9o(R`TNja?Z#h=Rz%R5Q zL+UQi(lHl6vUe#l^x|X#;&mXNZNkII<8P|EnDSonUr~f;`7X{}&u_=0**ruWxhtQh z@sR+TJs1Mkl)Jp6Q$$J71;M3@S+GAqA0=mXe7#ds(uvPoW=e#a!}upz9JAwtU+S_4pT^$!8|qA(&7XFTW>PI7KGJz3PoG z3EJr;V;o;b1(+a*p<$DOPxpxn_7rydlj;c@n8^!%Z5?Y*qH8av(=Z}bk6VLl!Hozy zVO(y}9+Z`j=>Hay1a_tnkYnksE_-U}U-%(DPe^zU-aQ{!Uf1HlMh3#Z6g|=3GPQrp zLHn#mXwMURZ6}-U(!P`?^2-Y#4rr37hZ&+MtcNed`o&6tW8whut7z|F7cZf_6Zm3- zJ-xAl$mH;gDh1rbb%9&ha7leIiR1fEow>K=QQ;)L8qI>7QdG~^M@JUf!K!jp7wVxv ztR!j4vmg?cID1flV)ZdnL%s2cAo*vmx2_C{)BCZ&C6`O(O^xIJ@Sn zol@g9B1<8k%v%ej1INqQ6EN7uItF# zuxy!4#vSwFJ^g+Z>vSsjacH!D7Xc}tP=qP?mwqPTZ$Vy;Z!O%=PvH%Lq;G$i+})b6 zQ7ZMatxvR`Il?1(6F~Am`}GFi-boCKaiG_dM+V&umIN5(~+^J zb)`g^PUSC~xKvk%a1&@N-fv9mU7owaPJ)9-en(JyGzxdL6Nu!d7GL2`FG64teDU(D z4md-}>l`&3$F$R=(*h!ak=}A;M6J<9(u~gC^nE{$%Bdy}N}$#L3;Vz9>n)4LOd6P( zZ4u;?%BipUQ<&VtN6sAS6L47sNNZ59IzsA(oWxqsScag=g?@eLa`_H$j?{@MiUs#(IBP77M!J#v?b4xPX3s zPmm$vmt$UsfDB=SiBv2&GK3CZ_L1o^M&@*fB@PkYwIa%b3Bd7DXNgjqeHH%$xBr^H z+dDDB##e@p7)$aL(HXN&?@BfQHj_){C`!T}WAi;4+g-p$_>N1k(vTyMwvn4jUgH4d zDPRuC6cNEJm+RvAMKC-zlw0?uTD>60aQuL5bic~v4DSAm>;A$lR-0+Lb42?QE1 zVxXJD3HbP0k+d5@2I^J9`TL>u$JkXZ_8>0rZdME-o)u#t)u*T5qaS+<<|x)piDj1S zaBL*b>xeXMCseV0YGl^a4i?ocgivUv8W8)@rq&xT#y^(dd?D8mZRUNfZUZUro4+f7 z6^e=6tee5cFLe&WB)|Mu8awjtF>|I2AM%=h@&-wJ9B{Ia<@Etl2tmMCbZ9$@IKC(A zh~Uu7=w3`ldtP~`z5v4yrA{d?(=MRHW^})Wl@x`z3PRy2MB(~tK8n9~GI&xmv~&t` zl+=0H&j%~0#Qh|*)}g!n;*FE)b13jksmsBfyJsYXJ4$>Q~Fhw*LK`xee0F{vIv^7>Y)h zwH!`4Y{L@eq>>o!-Ky3(Ep*I6a>(naBK^LwAV?cvp!OF`?>%bMiOr%Y^W8_-)_S9b z*rF&O;@rqG@KBV2z(+4!DgX$&NT`-aGwV!BL)KZXO9@C=$CxgbbmWC3y&Fnd3!O23 z;(_&`0KJ9?xHxnbG;0_zhwUTsMRB!MvvB0uREVVQ)prmxCGzcOf-Q69Mf^;PMj(_MDw(W}caO-V z%3dvsGs?t1j3Hm!1`R(ne9H6P_a;tv##B#Is@dB4GQpiw_QS2pxETb|#k+3G}?yyKDSGx}gUs@a5 zS5U`ZyDGtI)uJ~VZ{-J}I@jH)nm$iI+tIu>2@hL|39>2!{lOFpRWp`c&VGzy!T7K6RAC)?hi^*qMxn>< zm?d`L=D5tG>ct+;!k5%%A5H0fP2OBOF612BE{i4Q;lxpKA zK4qqkcba!Rzr1Zb*<%ImHTHCmPmLVdj}-)7X|pMi8ok{^6>5bBLpHrXzN{pxwp56+ zvJEOT+jx6je7J!P*i@N(Z$S2MhT_-&IFAVnZK58wwQI&)z&yg0Nboz5U}v?%VlcMy z5jvx2w|smlTMT#m<#xpns?_>dm*C74OQ)}nW2Tno>$r>#oKv*#cA-%W4oYyq(z`um;c59P|F3*3d* zCUH=7w%ftGOe$!-BMzP2=0ddXXmD91RJxDDYQ zuk3}^n<9?O%wFKoY&e%Zd6I_pAO&6dym4rI`iUxZro!p%!_bU~*uC0gJNoE7>* z-+oy`(Q7pAI^R ztZZ#bh;QmzcAC?!3eE*zCXvn?{HgR{8_xb~?N>|aWiT{IzqN)@A7z8eZ1y%&rRs9u zgie8JXmr&1x-pa1@7-!!HAKFOwSQeRGFU|sh8`ZHm+ z%b7n6dQWxm%+;!6da#tq{{Rza2&KlW z=jc}93~KdTc?Fx{(vJ`PT^DuHs92-Yes@|{``Lf3x~)r-Y_mkH&XnTCCcjItRWhs) z>EVH8Nwk9h{CJ)8-bjs7EoXkl5JvO4hL%0bmRlZ#%!iNw9->()?;C(VCJ>-Pm8V&x zcP*K|5J0*7_e{@%U6-c~eM8M@co@|H|qW9NdZBJRlFgP zDJd7Js;j+{oWfPbJ~vSMTaUK%d7Ks{S%vnVdQM`cB!wqWBb#HpBJHO5VN!y1z0Vsw z#5Qi*xb53JI|RVZ>Efd02nz{}0tLC?hckUbzA-9&k79ssDq7x`;Lac&0`VNoMZFJ2 zj)*QbtBym*+&@ibnz^OPASmC8p$#=7$n@g&?wq`T_-(0mAzCe5Px5wggDp1Iy0q*v zKoyN9691if$b2ErZP2oB%eQ+iG6KKw<4^j8O)Pb76~e=BfSf89`1gh0t2v~ zi>i}gnkK#R5F}$HKuN$k>RE6IBj8g9&{3zPLOok`unL$1NwvmY=7ZlFt;YqzTRQHn zRJZ2`gOUd32bg$ABFrI_yr}kO?|UDzIom7DwIi%Ks+exQ?cU`GRp->1JDIf^n+Paz zB)@y7b&k$|{;9o>{##goP>+FXF!Q&e;iS>+Xdk!B&>UelQg$05NH2=WvZbO7e%p0m z&dUP4-r&u&{GI^^e46>a;53J%(r)RekVY|IgO>$jYab1;60rX4Ey??XXdkQeol*>~ z%vocB{yW(6icZe5=zO&_;d~IRifyd(Q`ynf9#Tw?o>6JC5Cc+PxAvw}9 ze?J{0xH=B3zMA}!Dg!uC62K%3q7l3pKomVXOh7SLO#yk&+Wpw?k7W8Z%B}Fk)6c ze-opvYW>F7Vu%KnBa8d#O3=0qapjgsgb+ zS@)Tf$q#@j2*TS_U*<64SvB9F?yob6Vkt%R*PIhFdGp#As7OAJs`_Gqh%gNqApk=}IAPMu$^^W)ZxGbvd0@^&TzO zN#IdTj!%Am7zdIuH)p%h#W5aWUi7K%DEB~Sh$f*7AnO_CDs2pwu= zhWeXtW?gEtwL=GgoVXYPS{(}1BZMoQv!8Q03x+(j*~^lDx8FU>fhEP%062EZ?~}V&VE`FJ|g!eYAHW zS(m8`DN6wMXYZM}6pSn0B%E&1gjZT%GBN3}(9jV2E7G&}mgRswaxeIXmf;-$O^9}H zBvW@|VKB!Ryi?|of0{S>x2>qx!L%$k*SzzMxlv$R?Y3F1C<7-bTBW_`R!o* zZ%dZ|VC^wzpe&0qZ}Li_p}vz6Zrg4-%m_ks1J*}NBRXBE{jmZ~4;@3u?MbTh`ei*l zG;2m}a*R_pO1DbNNEOKie^&^@uMVE`JOWa?AT%(gH$l#lOQ`kd1%t|&nmr$*f72A=Qs*WrFk^2Ea3NnEEC zqycAVdh{(2{7Lv4>Ow6e?4!7ZAgnd(9Ydq~ivli3#FbKftbZ!dBUo=as{I zrxCO(Gkl3Gg*3GH?lHokb}SO9D+?<>@uKZ0nhU=_Sidg6g(wiJVs3s5DJT5Ct>;1d zY}IfF>DB0g$nS8^%C!;@FB#fKr9GGcYJRE{sp+s=(jL9`yD15Y32nZbqx#kCJGkvu z_t~?6xwDuAQ**z{Uqgr5_c14JHM-+Eo?*sN&{}NlSIsPfE@MPCFZi}CxlAawhE3zSycQy>ruI2zS#mQ=u#*!&UVpE zHj2t_*YpwTYwum|ZG)dBoz6=cc(!(l*y;^cVY3~5=sUOC&6q#8BBt`hsr(16jzH>+ zr_fofdM7NEk&3&Z4n%;8q-fM4MWk6D4s)V!h|hB*T!4^}(h+zcO#~p<2y)b2okiZ_ ztoNX1MR?RCIlSTG-rz}A z!wh|pS6FHh((QlHOc0j+`ux@CR_){Vd@+3@Z zlGJsv)axo*wfIY|as$QR55o(7L1h;|SoN#>^@Xr3&~85Mkt4?bAT#i4m(1WX%CkOI z#t9&C2PilPQo#=cTw4G>SV$o@bRr|e>Q(Aqq4S8gD%;Y2b~Opnq3rnJav%ro=keFZ zR&I%&Z+__ui3%PGWqq02l&dhieZj=FhF}7D77WDEbGoy!1o>yaK>$S&7|b_h4u}mW z?K=wxn0Tylrz2=qdF&^paiaW(cR4WikG3U53ie< zIb|DYPa##8Vh8LxWI?V^*lkFiKvcnHtW=yP9^PA0m^PDT)Xk=x`p2{mTX_~y3w2?F6ZH9^)8LlOoun9OaKmX|k@ZXn%RY{~;E>qH$!io#pjS z9!jK4rTr`?ysf;>(ZQTg{axaO(q-=(XS+1G9BIty@x~Y+NhV?-#E>E=5(UByS2>iX zI?eEGzT!M%CoBgn{=QETz)Ukwk==d1BM6Y$3O?4cjshuPgFRVjs(0pW|p(Xa)gx-ingy4p< z(iZfA(!BmALufT~=YzzRqs**#N|}$$S_R^9ov56QlR8YIZG1_Yo^mv4`G`veL^|9F zqTbF2=9-@cZZrl)IBo_Pl1vA5Lag$y9Lzj=A!uW@|5w=z;CP;b^09lBglN$&w+&*n z+~7a2aFxMEL+jH*<{0bOSrOiNh)^~RQa`qoxDNT;g` zk+T0eUxC}emPnm-|LAWwR!K)@ z<{7Hm#zlV26cTLWszW=zw-Y9x^hR7P9p5+;mIVI{)SY)-A_r)d$!7t=I4uk-JSo5_ zIKo`u#oThRdR4Enc(1--?+Hgc!S`N86w?^`ZCmD&=?yNEyWEcZ&MOIVOb>KNr04B( z#7LIlUN)(BKmLF!G`_m>@5N_o8jztB}A<Lwp&B%DlRZuN0oWi|kS{Xx|K$|1s{(L10Nk_3T8Ch>RY|$UWYvZ2 z6s51TfBMDx zhy-{0#eRC)YUTb^+)cRvYRe0Ej04y=*vsuCrk*&**m$o@rxqcSDFz9%I^Hb{(zi9r{H{tEghXiN=&^yX?27dt+$4cw7SF{ z_<5wbJ0sKg#}B{Ww$1p-EOX1E53hy1iw#d{y*76ndQpSAets(w_Br!P#XdGAtcf$M zP&Ru-hZ#*P;|}~CP2b{_)o;AcK$L^=dxzYIrtueqf= zkra{u6t;dLpLhdMs7U*j8albqOH-`+!{h_`nM5n`uk>)N9IdaF6gYIbC^Argnv)m% zNvZARrHlkMF(WzoE6dwa9FE_=Wb-9(%_1cnJd7ezC|33G+1-BV6DD$V2K0 zP6)y2cx8dN?e5tLX2k<@?zat%YgWp z2OM4O1B20hY}(T#9x+qAM&kM>U79=3aF?iDUK)&@X=3iVX*q<^7|=UD)$IO+y+q!? zjO&kYJHQbSUls)3U0>^N=}4ruvft!bI@bBreB4^W)0Ld1uaFq^^#MD?yF)Cw#ZeSheU&Q0Tr7XD9tRKg;jAT5h*JR3% z?sXFSnRg<9UiNsvMPwEz;Iukw+Um2|QFHV9_!2m5o;?J$1!FL$_~F0q{w(%H^6E_3 zMd#PA?H|{coF2>=YDW&~LXDPM?_;q4I=?za&%G&B2<;)@7|6~Jw)+DGYTWVkKpJCR z8*#pt`C9lQNqZ+e2mQZuSEr77i8Oo)IKTPgZZ&pp(29q>ZM8 z39VtMvkUk)-LG?Bc}9sFV!lF_A~0*nNzIW41BxXoVc@^Bl$xaDZ-C%B5d08XUA7*& zqeG@i!tl^6B?M!COLj&`#n(8o`=hG;%%=F5xyf0gy zWfqecg=LNAnLPG&%SU0918{!@!nc3QS6!81FX;S3AL@vyLv0HxaMdLQ(Dp5R5y>Fc zL=PHjo@pjMy3(->>wh0D?u(R#4C z-;$UtRZ}B8cFI|J2bqx>CN&V+kW@Lu+*uMr zWs)aQtCTfVsZHydg?*Ln`Xzi@9-E3jb1LO^WTGF4?Ul_-6G=T)8wk`BU-Jv=yZw3Y zI*MG;r)wDc`dec{LNE1<7iD+)FkY&6dd+=OgKexpct-P?O1BQh)_2a8Z8tViaAXhhVrRGg4>4pfrfG* z;ygay7(kvK$kDj|Y}S%9An`m@I+F?6es10joys9N$sT%rGtiq9f1DP=F%pI<^e2v6 zdKRAMvy7me+oTk-K9N=r{3@vlZipa_G&li~@7;MGC6>Lfk}dyA^3>+fbeP-4<`@Ap zU9cTRv@5|2G@Vxmm~D4@nJ9A&sOZWj8lSU0Xe*awY3B*C!$j_5!T1zUM9GZ-mZ?jtu+4<^bRJyE9lv+ftR5^!qI%~jc;qB zLxOj-Qi!l2gVgu_Pyk3!?s{=a>y>$1Jn=kHVb^*-)C-KNE-02VT`)&E@2@V z0s`E-np=@iCLp<#IEgMHcwZF^=WLIiT(pM9SYh$yV5`}_$v^`ZR2g+SoRkW~loZ$~ z(GCku0omDSDlV=h5j@Wzd8@VI$hJd>l0(qJkzzzzw}W(eT0U!7oBBg17w z1mKC_^_*8kPUIZ3wdyorh})LHfsW1ZaYWPI4Rifle=ed>jD7$2`u4 z3lH<~RxzIVHTJyFh|1hGwfTA>hZlQO;suf{hs1tvV+i8rj3qCu_z5Y!B+#TOO_qN0 zCPnK}uGuabQ>Lp78v4K~G?~=4IC+tw2l`tR6mNQ8YzYgJLRM~p*hcQt4>+iAbOb|P z!blHM2;b-|`czzY6)L@&>N9sf7@=A2JC}bPgF&;S(`pkZ2bQskraom-k}>^*?Kc<* z35I#T{3LDf@s~{L>A;v5mXwtY*Cxou(r7>cE4T4^3XO1wdJT8&Ug!%-y~)~!TxC=Mjn9$l0DJYS7`(G8 z{AQ>S<N1(*NwkA!E_sqIaYb=NWUU z5%(BOyO=M8``nd4dGod(H6Yj2qt|WK^GXt#|CUAOzrXkz2?AK{b6Y8*PmIOq@Ld@Rmt)wpEMOYYgi0+f@3WWd+$Z@Mk0{JTwHR>KyzAO@E<~rv7#xMuV^V}(F_1!8Ea#+2y8Ve?- z925N&g5doq?WLsBAdrL4TyN5HLe*%JCQf2v6t(yIgp2E{@^KuWPWWYv>1E zB6Z4egGmb_c^=3|AB0I!=#1}W&D{Q$SeGLt+DQ^xzF93xuU@k?a^fY7QZDk3WwmBkLl`8zJrqM!I}_eJSvzrfKK!go_v8xj~Ze<5l*}Dei)x)$w z&=<3iKF_At)Z;p~oVpYlVpPiibYda$&mCCl z)ASA>e$M~=XmY!nHaZd8u7)WAI?|;xCC*K!m}E!KnATk6oZ-yS?vAtf07vG#K8lf= zm!t=^ky^NuyM|=~yAlCl=FsRxXz$}gS_!EP5S9wSO9a}s1d8v2R~^F888;8@CGoL( zmsMh1frxzKGq%uDFvpbCREXTODM*%i0So3j0U#7E!4heXxyYRT>!iLXp<6?Z@9HG< zef;xJC7~ftIx*IK(=y6m#wd*%dd&+pm{ER2+30JbepK_B=1#Xh(kgP96?_>dO^E$$me z7_A_!5h7F>_aq-fFVZEfj@a-=Vj%7>KfD8yZEwXlGfY_|WE{{vU4_};00VDq$LuIA zTj@r=X7=E?CR^16E9J_U?E9C`#(eAgo)v*`XV&Y&aFWy{>m)5UbIzFff6bCv-v}X- z^b|CJLkR!yu~P!Lu!|0?walhwtB#l=o`Uqf!I3}WB2qr%eRJWIJY4}##1BE0V@}l` zvV9E~np#X(U<~D7nhOXL z$l^nr2qwmijMM>(%w#Y&A}~}0f9BFuD{(apaxMUBW|h7^Ffqp73C|&EgW^US>%bqemgdif&o2%$ zwlKc5lS3aJeVEn35Otow&O)oGBzbM6e6Sn-B7I@mhSdg*KzzV6uD45_WsyGj!VEaG zDa#b4Cx)Xz@3**2J{l5pL(%Yjiqs)8a#SYi)c~FY9kS{xc_$54?3a%_4Sp!euP3Bo zJ`A0vH2Ddt=x_VpK4qqkLFM>#mwj+M=8>Ia)4Hng-nwSxD{rToCbdOH{m`0(W}X@k zwEgDi1JqxsZ2knvVYq%f=#k_7`GSbFp9&BJ5J+jjflV~BIr;_ASOl67!C73GDoMB~ z!a77xD;WMC+VM9UP^JRerqHSLz@!ltf zsnmoWpYjWel;$N>-w1f+nWQGRP-xdR8#V_oK4It{c90=ABlcqPls&QOc9kpXMNGm*D`$TupxR5~D(qf`m-6ylmQZK8x-yNg7!b)@-`bmFr zHTfw=?iaZ7t?H-!sW`YEQFg|awG_76``0*Y7-9`$Fr=N2lz0vZ*1fM^@%~~CR?ach zSK0fbCWvrsTktR0apI zO=3JUgR^~?a&li(X<(up1TO|2_U)8Nx7g->i_DV2f4*M+C{EaJH_<8ahr6^ar&#ip znF~dZ==|G{9MUXgAN=~rfd_IP0H+nIAMq&2es+ZC{nL-8SgoX(t09I=KirB(z0zZ; ze3Re_0xCOGA&)MJN<3-bUEum-=7mZYC4lw%6;veC=RxvgBj>%BgA!bOAN#QfHgivc z>sxViKu8rpP^0>~m6`Ybt9HeK1!CCpw9q<6^=im{B>$qZyL8IOkyYH z9nx3WZCbpc&B!}sOL%Hao+q5>LXjy`Gd572=y@1E%3oD?n$?Yk&y!BY*9E1@K{6=; z1Jw@Ph|+I%FNz!x984j!4A9uu&7V&<6(Ip&>y%*fr<+b37RtZb``y&}FU9hdG4 ze>Nq`9s1(||J-$cg+0bk32U&Bw%O^l5xpZX6cw$Zz#QE4|eCIGD`!>4(Vlj7mw256u%DUx%bUmQh`^LZBwSy_ncz~+AG&G z0?9ECU)Q1d{S>0$h=l85g9^huvpQ1KRfa*-PHW8a&u?fbXw7d&<9x*u-QUU%8j*A8 zkeh6!(h)WN@JCe`jWD-eN#Tdp(-oz6*Nn=9P39ys<~0s_emLUS71zt7e^Th8fpRAk zp)lO>mh-F?lbfF@9#|#7R+u_4%qV6*cBARukdVWsrijNYSu`9AR9dLstG`v5l;|O~ z8kNT=P8AhH~fmDc}a6JU{BtwU#@234eB4zkG%Pm1=G z=~$W2BC9Laa~&@pLlmyucbx#2+d+F;CFW<8_gdLl@T0#j|GL+%{_hyW`0PrWd$0}? z|Ij49{6Q#k%pX8cq!@tk)qjx9K?0jH2n;PLsRa*dSc|j_$lf> z1dNp62ffe?TiRmL#H*T?e=Ue9ubSBGHQbk{h^tW$;B}fT{~BoawapYzmj@oM5XvCw zMJF>(YUSwE=Mv6togzB%`gtx%PDxb3{_=A3a#hM9Be&kfD zo3Px*XcY8(GWW2zS#ifTiYCRTed~3|58?hgxhf+1qR-dc#|pW7nUYI44Y!+owv>$5 zYr;)#wx7KhF)L0IHR{^E-FfeK+7e(r9*YzoB_Op$)evN-3^f&R_xLl#Ba#AlS}TDU z1Eq~+TSA%NOnNibxI1t-U~QE)nS?@KwGjz(nG)V`+sqscSzb4?l3bR}k>>fWX~X2( zP0ghn`=E7%Hv-427u!Bl0mD8@eCR$0lY$F)lLpD*xO;_cmg&*jl_s_0#^NM8)oC@= zmw+AuooyPU^)+BOxt*g(J?kd&isvJ~bY)|>ujjQFi=H$pI_{I@UDdqKLTfI_ZPz;- z9I3fkLvQ#a`|~Wa9oi>HoL0!E41gxgxBpCwsup18M2=2Of@N zley*FES1&#+_%%}=U$T)9S9tc2i-tD)Q0kg2vU;)>;XB&h#Pg->3)%1lKJ!SVnpaD z++eY(i2R-W0RY&i6od&(r!&u9Fq(vWQqVf2;WoXhZJX?$gehzG__}1ze;xa!s_RT} zVA;ewMV?2gVJz91mCai`kgH@%e=xNH%pFBKv5{!Ntm$r8Sl=s8213vt(*Z^=PL0_2ThVw*^ z%GhT#%!m4%U;Qi$E4`TrzX>lr3&rih{Am&2TOJsMA5D7paJ0?*({GJ|#&R3|w<@3_ z{OyUHWZadl1!r4@D6A8Tb{{TjMY0*ud+Z}p0%+@^twyvSW!+m%Qcx#G#piJIY8~#- zh4A#Og$TcdT7%Li#`$4CoGd+#9Q%}Wa-z=^tg)Xl^m;9{$gdKsd8o8zr${|VpgZiX zul6SFBbEpKma;6eFeY*S1EGN$Fd&fZRo;2@AK+rRDR9VNjQz`Og!voS{!b>Cyx+xO zYX=e%ydTEgoxcV*NZxSJ8Ek|*Dg&4iLjm(ql1p33fBh!`qKSw6Co)2bkRy z23ZW}@lcJl4x_KAQcj)WM+}g|sphKiQcni#_T%Uf8qi7--UTHc}Wy9%gs} z6uE>?odd;qKnwwa<>PNKwGMa6+#3ZJw0vfrUzB1BHC25-zli^wP-k=D$PuYYD_}-@ z(5EuenMrFNZScy85L1#w0e;>c%;fob1lv19dgIIx?{ZX~1CoQeVG0Oa4RdXvbj6k8eP^v_BQV=CMp<_h&yAKk z%aqko2HG3baK9(yB!Ps5+R4LrA@?SZ6YY#Bgke-a0lwNjfXSMM!;#~zMh|y#UhXpf zsu`*MBf0X2!)F@}iP^Ul4E?DU#z>$XhriAdo#2|`ksaRRp!>N&y^MQ+T6(^_VCPOWbbQTdf zh2w=^k2kz*CwY)qI*SzcYV@c0f7PC!4@VNk6u!*k+j^IRZyYGtKFI9<;WRBPFMHLdut3s1%mufL-(2 z?SVI8M-we+sN=KG6d=cIDWMEDXuA{8&IcP@V9IH-R;aKrYZC$6#YNxAy~n`~2SgUK zrfLKvk$_YZ8u+s?FrAtjimpid6@DiE?N#>(_XacFXp#8W=vwM?pnPEi>UNZ}99e59 z>(vVpjW`0vH6Yy!OCazd3<=Bhdp?HCARU?gDTN+y88!fR3h>H)I!`*$O*tx{)4&bq zUesoI;d`6%LJ}smdm<>~)eB=l_D2CrmY_yf4`K;KsRQkE02eV)ttBD+#i7jf$(2XX zfOVHrgH6|OKMCu$Ju@zeC_THx*UDGeC*4tM`m#tH9lpJqFWMpPD6=vMOqbxzOzrwZ z;OiBwv>X{1NLY366l4%cpZieI8^GC-=Trcuj0=k++@>}3OiWd>T)G8f$sjnt<2rp+ z`slclA`OUl^84z*Re{`Xl8BZS*{nk-;c|(u76Y{ofUMHly%f)>MTaR3!vjW z3U!rQPp`neW9B}6ko5NM1ps;*!lES?Bjs4_6RkaZ_3|gU?iUangu)jZ>-xZlo5%nQLAj%KE_F|RvlQY$M<+xG0sk2NNSe~fP71*B{kA47Wy4E3 z^&+8XV^i#di-=W>_s1!Y&I<0yVJV!H(-a2IoDUsk>?6eF?;|)~LO^+AJp_E%{t-&2 zYCa_8{k=v<6lbUpcO@&I=kZuQr><NGh_E8!eS@&tnMnx{)0J$_J`nzK) zL185OfGj^4co?o5y$|{Q!*mcPc2yKW+D6CY*sx!KgWTx4DZCWrO~+|V;x$4OBYy!~ z?!u`97#`{LrQmsp3-N82%9J4|T!owwfaQ^Lx0C@!1f>u>^OXH}O#}3sY^YS_at%ox z38RP1@Qw1!O08(@cxern@VqF)GV?p>yuH;PVF70N9c=frru%+0t#nD9u%*{~lrMyX zq|(F#h|o9o+Sfbv?sd5tR^Da4(I*5X-4AO^*M37A5n&x)l{&Uc1YSrfYCzjAT@^59 zxlHdH#O{MZJMbvzVaNUX5EkSBE?2V}|7@>HDE?iPKigIjUpY}t`lgrm=Xb3&Wn%t9 zdu`mgWkc9b_4tyDrO-b<0d4jK`QddQI7{gN{;(w@L1K^}+Po1OhlS_77ItUl7FOD` z756p`SO2piOqu47=o*Im7j>=w0-PdX11>UoB`w_ZDUuJZ`8}d}ia5Ik%P*m?eyXf- z_a)J^ad*K?6L72nd%IKSW-!MQCL=jQC*d(2|x{5=o25NrC^?X&RbWk9$|K6y` zaR91Qbp7RGW5-3eDq6)r8tWV&Jij47Z%oL)|=_hIado~KFwc;77iCW74Hf&ef z!*7H&P4*PM_FJ^a`6C^>vue_|k!pxES(U*kMU|xU4ge~Pd=iPg#J)OBc7w(%nr#Y1*%Q+?Ow%X-LmLEHgCWtw z^xv&>(me_qU9(azdJn|7sP5Bd5+DeY^Qr?(_Zb%inxqg>K~3`JZW zv^n?g3YfJJC_!aIwgZc>B@U#J{U^XcFtXE9jQD?aQjAVjUtEqwCw>xV7id95@(def z!=2R=EQI_PKsNfIm<&xGGhj(;;*bBC>p-v!kSdD_{GVVH=v|&G2rCZ$ahKw9^>2|d zS%4Nb-V8?M>R>^b5-6eL?k$%%>{C!32E#$9OqlvPE($Tnf9J2rKweyY?b)92$bXIw zNyonj0Ypd`!1BX6*}Z}<{*OQY_X!Phz+JJRPi)+i{=aWQ{?`?VSpUDcE9fu!#pa^% Uixp@b3h?t(_PI>0lu7Xa0uiWG?f?J) literal 0 HcmV?d00001 diff --git a/src/content/changelog/workers/2025-04-07-fullstack-on-workers.mdx b/src/content/changelog/workers/2025-04-07-fullstack-on-workers.mdx new file mode 100644 index 000000000000000..3418c2b8424a7a3 --- /dev/null +++ b/src/content/changelog/workers/2025-04-07-fullstack-on-workers.mdx @@ -0,0 +1,38 @@ +--- +title: Full-stack frameworks now generally available on Cloudflare Workers +description: Cloudflare Workers now provides production ready, generally available (GA) support for React Router v7 (Remix), Astro, Hono, Vue.js, Nuxt, Svelte (SvelteKit), and more. +products: + - workers + - workers-for-platforms +date: 2025-04-08T18:00:00Z +hidden: true +--- + +import { Image } from "astro:assets"; +import fullstackWorkers from "~/assets/images/changelog/workers/fullstack-on-workers.png"; + +Fullstack on Cloudflare Workers + +We're excited to announce that the following frameworks are now fully supported and **generally available** on Cloudlfare Workers: + +- [React Router v7 (Remix)](/workers/frameworks/framework-guides/remix/) +- [Astro](/workers/frameworks/framework-guides/astro/) +- [Hono](/workers/frameworks/framework-guides/hono/) +- [Vue.js](/workers/frameworks/framework-guides/vue/) +- [Nuxt](/workers/frameworks/framework-guides/nuxt/) +- [Svelte (SvelteKit)](/workers/frameworks/framework-guides/svelte/) +- And [more](/workers/frameworks/). + +The following frameworks are still in **beta**, but will be fully supported and GA in the next few months: + +- [Next.js](/workers/frameworks/framework-guides/nextjs/), supported through [@opennextjs/cloudflare](/https://opennext.js.org/cloudflare) is now `v1.0-beta`. Those using the OpenNext adapter will also be able to easily upgrade to the [recently announced Next.js Deployments API](https://github.com/vercel/next.js/discussions/77740). +- [Angular](/workers/frameworks/framework-guides/angular/) +- [SolidJS (SolidStart)](/workers/frameworks/framework-guides/solid/) + +You can also build complete full-stack apps on Workers **without a framework**: + +- You can [“just use Vite"](https://blog.cloudflare.com/introducing-the-cloudflare-vite-plugin) and React together, and build a backend API in the same Worker. Follow our [React SPA with an API tutorial](/workers/vite-plugin/tutorial/) to learn how. + +All together, these new additions allow you to build and host projects ranging from simple static sites to full-stack applications, all on Cloudflare Workers. + +**Get started building today with our [Framework guides](/workers/frameworks/)**. Or, read more about our updates to building full-stack applications on Workers in our [Dev Week 2025 blog](https://blog.cloudflare.com/full-stack-development-on-cloudflare-workers).