From 538f7820680b2a3d657c00bd7e0b8f20b53df7b1 Mon Sep 17 00:00:00 2001 From: Gregory Schier Date: Tue, 18 Aug 2026 10:39:17 -0700 Subject: [PATCH] Serve the web client from yaak-web (#582) --- .dockerignore | 11 + .github/workflows/release-app.yml | 2 +- .github/workflows/release-web-image.yml | 115 +++++++++ Cargo.lock | 64 +++-- Cargo.toml | 4 +- Dockerfile.web | 46 ++++ crates-server/yaak-send-proxy/README.md | 139 ----------- crates-server/yaak-send-proxy/index.ts | 4 - crates-server/yaak-send-proxy/src/config.rs | 52 ----- .../{yaak-send-proxy => yaak-web}/Cargo.toml | 8 +- crates-server/yaak-web/README.md | 219 ++++++++++++++++++ .../bindings/gen_models.ts | 2 +- .../bindings/gen_web.ts} | 4 +- crates-server/yaak-web/index.ts | 4 + .../package.json | 2 +- crates-server/yaak-web/src/config.rs | 67 ++++++ .../src/guard.rs | 33 ++- .../src/limits.rs | 0 .../{yaak-send-proxy => yaak-web}/src/main.rs | 74 +++++- .../{yaak-send-proxy => yaak-web}/src/send.rs | 14 +- .../{yaak-send-proxy => yaak-web}/src/wire.rs | 16 +- .../yaak-rpc-schema/bindings/gen_models.ts | 2 +- crates/yaak-models/bindings/gen_models.ts | 2 +- crates/yaak-models/src/models.rs | 2 +- crates/{yaak-web => yaak-wasm}/Cargo.toml | 2 +- crates/{yaak-web => yaak-wasm}/build-wasm.cjs | 0 crates/{yaak-web => yaak-wasm}/index.ts | 0 crates/{yaak-web => yaak-wasm}/package.json | 2 +- crates/yaak-wasm/pkg/package.json | 17 ++ .../pkg/yaak_wasm.d.ts} | 2 +- crates/yaak-wasm/pkg/yaak_wasm.js | 9 + .../pkg/yaak_wasm_bg.js} | 8 +- .../pkg/yaak_wasm_bg.wasm} | Bin 4256426 -> 4256618 bytes .../pkg/yaak_wasm_bg.wasm.d.ts} | 2 +- crates/{yaak-web => yaak-wasm}/src/lib.rs | 2 +- crates/yaak-web/pkg/package.json | 17 -- crates/yaak-web/pkg/yaak_web.js | 6 - greptile.json | 2 +- package-lock.json | 24 +- package.json | 4 +- packages/platform/package.json | 2 +- packages/platform/src/web/README.md | 38 +-- packages/platform/src/web/commands.ts | 6 +- packages/platform/src/web/connection.ts | 2 +- packages/platform/src/web/index.ts | 8 +- packages/platform/src/web/proxy.ts | 71 ------ packages/platform/src/web/send.ts | 34 +-- packages/platform/src/web/server.ts | 83 +++++++ packages/platform/src/web/worker.ts | 4 +- vite.config.ts | 2 +- 50 files changed, 809 insertions(+), 424 deletions(-) create mode 100644 .dockerignore create mode 100644 .github/workflows/release-web-image.yml create mode 100644 Dockerfile.web delete mode 100644 crates-server/yaak-send-proxy/README.md delete mode 100644 crates-server/yaak-send-proxy/index.ts delete mode 100644 crates-server/yaak-send-proxy/src/config.rs rename crates-server/{yaak-send-proxy => yaak-web}/Cargo.toml (82%) create mode 100644 crates-server/yaak-web/README.md rename crates-server/{yaak-send-proxy => yaak-web}/bindings/gen_models.ts (97%) rename crates-server/{yaak-send-proxy/bindings/gen_send_proxy.ts => yaak-web/bindings/gen_web.ts} (93%) create mode 100644 crates-server/yaak-web/index.ts rename crates-server/{yaak-send-proxy => yaak-web}/package.json (61%) create mode 100644 crates-server/yaak-web/src/config.rs rename crates-server/{yaak-send-proxy => yaak-web}/src/guard.rs (89%) rename crates-server/{yaak-send-proxy => yaak-web}/src/limits.rs (100%) rename crates-server/{yaak-send-proxy => yaak-web}/src/main.rs (69%) rename crates-server/{yaak-send-proxy => yaak-web}/src/send.rs (96%) rename crates-server/{yaak-send-proxy => yaak-web}/src/wire.rs (89%) rename crates/{yaak-web => yaak-wasm}/Cargo.toml (98%) rename crates/{yaak-web => yaak-wasm}/build-wasm.cjs (100%) rename crates/{yaak-web => yaak-wasm}/index.ts (100%) rename crates/{yaak-web => yaak-wasm}/package.json (88%) create mode 100644 crates/yaak-wasm/pkg/package.json rename crates/{yaak-web/pkg/yaak_web.d.ts => yaak-wasm/pkg/yaak_wasm.d.ts} (98%) create mode 100644 crates/yaak-wasm/pkg/yaak_wasm.js rename crates/{yaak-web/pkg/yaak_web_bg.js => yaak-wasm/pkg/yaak_wasm_bg.js} (99%) rename crates/{yaak-web/pkg/yaak_web_bg.wasm => yaak-wasm/pkg/yaak_wasm_bg.wasm} (85%) rename crates/{yaak-web/pkg/yaak_web_bg.wasm.d.ts => yaak-wasm/pkg/yaak_wasm_bg.wasm.d.ts} (94%) rename crates/{yaak-web => yaak-wasm}/src/lib.rs (99%) delete mode 100644 crates/yaak-web/pkg/package.json delete mode 100644 crates/yaak-web/pkg/yaak_web.js delete mode 100644 packages/platform/src/web/proxy.ts create mode 100644 packages/platform/src/web/server.ts diff --git a/.dockerignore b/.dockerignore new file mode 100644 index 00000000..50e4b2fc --- /dev/null +++ b/.dockerignore @@ -0,0 +1,11 @@ +node_modules +**/node_modules +dist +**/dist +target +**/target +.claude +vendored +**/vendored +*.log +.git diff --git a/.github/workflows/release-app.yml b/.github/workflows/release-app.yml index c20901b5..6c519594 100644 --- a/.github/workflows/release-app.yml +++ b/.github/workflows/release-app.yml @@ -103,7 +103,7 @@ jobs: run: | sudo apt-get update sudo apt-get install -y cmake ninja-build libwebkit2gtk-4.1-dev libappindicator3-dev librsvg2-dev libnss3 patchelf xdg-utils - # crates/yaak-web compiles SQLite to wasm via sqlite-wasm-rs, whose C shim + # crates/yaak-wasm compiles SQLite to wasm via sqlite-wasm-rs, whose C shim # uses C23 [[noreturn]] and expects a freestanding wasm32 target. Ubuntu # 22.04 ships only clang <=15: 14 rejects the attribute, and 15 falls # through to host glibc headers ("bits/libc-header-start.h" not found). diff --git a/.github/workflows/release-web-image.yml b/.github/workflows/release-web-image.yml new file mode 100644 index 00000000..fc07b25c --- /dev/null +++ b/.github/workflows/release-web-image.yml @@ -0,0 +1,115 @@ +name: Release web image + +# Builds ghcr.io/mountain-loop/yaak-web: the browser client and the server that serves it. +# One image per architecture on its own native runner (emulating a Rust release build is hours), +# joined into one multi-arch tag at the end. + +on: + push: + tags: [v*] + workflow_dispatch: + +permissions: + contents: read + packages: write + +env: + IMAGE: ghcr.io/mountain-loop/yaak-web + +jobs: + build: + if: github.repository == 'mountain-loop/yaak' + name: Build ${{ matrix.platform }} + runs-on: ${{ matrix.runner }} + strategy: + fail-fast: false + matrix: + include: + - platform: linux/amd64 + runner: ubuntu-22.04 + arch: amd64 + - platform: linux/arm64 + runner: ubuntu-22.04-arm + arch: arm64 + + steps: + - name: Checkout + uses: actions/checkout@v4 + + - name: Set up Buildx + uses: docker/setup-buildx-action@v3 + + - name: Log in to GHCR + uses: docker/login-action@v3 + with: + registry: ghcr.io + username: ${{ github.actor }} + password: ${{ secrets.GITHUB_TOKEN }} + + - name: Build and push by digest + id: build + uses: docker/build-push-action@v6 + with: + context: . + file: Dockerfile.web + platforms: ${{ matrix.platform }} + outputs: type=image,name=${{ env.IMAGE }},push-by-digest=true,name-canonical=true,push=true + + - name: Export digest + run: | + mkdir -p "${{ runner.temp }}/digests" + digest="${{ steps.build.outputs.digest }}" + touch "${{ runner.temp }}/digests/${digest#sha256:}" + + - name: Upload digest + uses: actions/upload-artifact@v4 + with: + name: digest-${{ matrix.arch }} + path: ${{ runner.temp }}/digests/* + if-no-files-found: error + retention-days: 1 + + publish: + name: Publish manifest + needs: build + runs-on: ubuntu-latest + + steps: + - name: Download digests + uses: actions/download-artifact@v4 + with: + path: ${{ runner.temp }}/digests + pattern: digest-* + merge-multiple: true + + - name: Set up Buildx + uses: docker/setup-buildx-action@v3 + + - name: Log in to GHCR + uses: docker/login-action@v3 + with: + registry: ghcr.io + username: ${{ github.actor }} + password: ${{ secrets.GITHUB_TOKEN }} + + # `latest=auto` tags latest for a release tag and leaves it alone for a prerelease + # (v2026.2.1-beta.1) or a manual run off a branch. + - name: Tags + id: meta + uses: docker/metadata-action@v5 + with: + images: ${{ env.IMAGE }} + tags: | + type=semver,pattern={{version}} + type=ref,event=branch + type=sha,format=short + + - name: Create and push the manifest + working-directory: ${{ runner.temp }}/digests + run: | + docker buildx imagetools create \ + $(jq -cr '.tags | map("-t " + .) | join(" ")' <<< "$DOCKER_METADATA_OUTPUT_JSON") \ + $(printf '${{ env.IMAGE }}@sha256:%s ' *) + + - name: Inspect + run: docker buildx imagetools inspect ${{ env.IMAGE }}:${{ steps.meta.outputs.version }} diff --git a/Cargo.lock b/Cargo.lock index c8639ef0..c12ef146 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -3284,6 +3284,12 @@ version = "0.1.5" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "21dec9db110f5f872ed9699c3ecf50cf16f423502706ba5c72462e28d3157573" +[[package]] +name = "http-range-header" +version = "0.4.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9171a2ea8a68358193d15dd5d70c1c10a2afc3e7e4c5bc92bc9f025cebd7359c" + [[package]] name = "httparse" version = "1.10.1" @@ -9548,12 +9554,22 @@ version = "0.6.10" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "68d6fdd9f81c2819c9a8b0e0cd91660e7746a8e6ea2ba7c6b2b057985f6bcb51" dependencies = [ + "async-compression", "bitflags 2.11.0", "bytes", + "futures-core", "futures-util", "http", "http-body", + "http-body-util", + "http-range-header", + "httpdate", + "mime", + "mime_guess", + "percent-encoding", "pin-project-lite", + "tokio", + "tokio-util", "tower 0.5.2", "tower-layer", "tower-service", @@ -11675,29 +11691,6 @@ dependencies = [ "yaak-ws", ] -[[package]] -name = "yaak-send-proxy" -version = "0.1.0" -dependencies = [ - "async-trait", - "axum", - "base64 0.22.1", - "bytes", - "clap", - "env_logger", - "futures-util", - "log 0.4.29", - "serde", - "serde_json", - "tokio", - "tower-http", - "ts-rs", - "url", - "uuid", - "yaak-http", - "yaak-models", -] - [[package]] name = "yaak-sse" version = "0.1.0" @@ -11776,7 +11769,7 @@ dependencies = [ ] [[package]] -name = "yaak-web" +name = "yaak-wasm" version = "0.1.0" dependencies = [ "console_error_panic_hook", @@ -11795,6 +11788,29 @@ dependencies = [ "yaak-templates", ] +[[package]] +name = "yaak-web" +version = "0.1.0" +dependencies = [ + "async-trait", + "axum", + "base64 0.22.1", + "bytes", + "clap", + "env_logger", + "futures-util", + "log 0.4.29", + "serde", + "serde_json", + "tokio", + "tower-http", + "ts-rs", + "url", + "uuid", + "yaak-http", + "yaak-models", +] + [[package]] name = "yaak-window" version = "0.1.0" diff --git a/Cargo.toml b/Cargo.toml index 69acaf2f..772e679d 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -22,13 +22,13 @@ members = [ "crates/yaak-templates", "crates/yaak-tls", "crates/yaak-ws", - "crates/yaak-web", + "crates/yaak-wasm", "crates/yaak-api", "crates/yaak-proxy", # Proxy-specific crates "crates-proxy/yaak-proxy-lib", # Server crates (the browser tier's hosted send executor) - "crates-server/yaak-send-proxy", + "crates-server/yaak-web", # CLI crates "crates-cli/yaak-cli", # Tauri-specific crates diff --git a/Dockerfile.web b/Dockerfile.web new file mode 100644 index 00000000..dba755cc --- /dev/null +++ b/Dockerfile.web @@ -0,0 +1,46 @@ +# syntax=docker/dockerfile:1 +# Yaak in a browser, whole: the web client and the server that executes its sends, in one +# image serving both from one origin. +# +# docker run -p 8080:8080 ghcr.io/mountain-loop/yaak-web +# +# See crates-server/yaak-web/README.md for the knobs. + +FROM node:22-slim AS web +WORKDIR /app +RUN apt-get update && apt-get install -y --no-install-recommends \ + git python3 make g++ ca-certificates && rm -rf /var/lib/apt/lists/* +COPY . . +# `npm ci` runs a prepare hook (`vp config`) that shells out to git, and there is no .git in +# the build context — it is ignored, and in a worktree it is a pointer file anyway. +RUN git init -q && git add -A \ + && git -c user.email=build@yaak.app -c user.name=build commit -qm build +# Empty means the tab posts sends to its own origin, which is what this image serves. Set it +# only to build a bundle for a deployment whose server lives somewhere else. +ARG VITE_YAAK_WEB_URL="" +ENV VITE_YAAK_WEB_URL=$VITE_YAAK_WEB_URL +ENV YAAK_TARGET=web +# crates/yaak-wasm's wasm package is committed; rebuilding it needs a clang with a WebAssembly +# backend, which this image has no reason to carry. +ENV SKIP_WASM_BUILD=1 +RUN npm ci +RUN node_modules/.bin/vp -C apps/yaak-client build + +FROM rust:1-bookworm AS server +WORKDIR /app +RUN apt-get update && apt-get install -y --no-install-recommends \ + pkg-config libssl-dev protobuf-compiler && rm -rf /var/lib/apt/lists/* +COPY . . +RUN cargo build --release -p yaak-web + +FROM debian:bookworm-slim +RUN apt-get update && apt-get install -y --no-install-recommends \ + ca-certificates libssl3 && rm -rf /var/lib/apt/lists/* +COPY --from=server /app/target/release/yaak-web /usr/local/bin/yaak-web +COPY --from=web /app/dist/apps/yaak-client /srv +ENV YAAK_WEB_BIND=0.0.0.0:8080 +EXPOSE 8080 +USER nobody +# Overriding the command (dropping --serve) leaves the stateless send executor: +# docker run ghcr.io/mountain-loop/yaak-web yaak-web +CMD ["yaak-web", "--serve", "/srv"] diff --git a/crates-server/yaak-send-proxy/README.md b/crates-server/yaak-send-proxy/README.md deleted file mode 100644 index 32474f11..00000000 --- a/crates-server/yaak-send-proxy/README.md +++ /dev/null @@ -1,139 +0,0 @@ -# yaak-send-proxy - -The network half of Yaak in a browser. - -A tab can't see an HTTP response the way a desktop app can: CORS hides most -headers (2 of 8 in a typical response), redirects are followed silently, and -there is no timeline. So the tab renders the request and posts it here, and this -process puts it on the network with the desktop's own engine (`yaak-http`) and -streams back everything that happened — every header, every redirect hop, DNS -timing, the body — for the tab to store. - -It is a **stateless executor**. It keeps nothing: no database, no files, no -sessions, no cookies between calls. Every byte it sees comes from the tab in the -request, and every byte it returns is stored by the tab. Restart it any time. - -## Running it - -```shell -cargo run -p yaak-send-proxy -``` - -Listens on `127.0.0.1:9227`. Then run the web build against it: - -```shell -YAAK_TARGET=web npm run dev --workspace @yaakapp/yaak-client -``` - -The tab looks for the proxy at `http://127.0.0.1:9227` unless -`VITE_YAAK_SEND_PROXY_URL` says otherwise at build time. - -Every flag has a `YAAK_PROXY_*` environment variable, so a container needs no -arguments; `--help` lists them all. - -| Flag | Default | What | -| --- | --- | --- | -| `--bind` | `127.0.0.1:9227` | Listen address. `0.0.0.0:9227` inside a container. | -| `--allowed-origins` | `*` | CORS origins, comma-separated. A hosted instance should name its web origin. | -| `--max-request-bytes` | 16 MiB | Largest rendered request accepted from the tab. | -| `--max-response-bytes` | 64 MiB | Largest upstream body relayed before the send is cut off. | -| `--max-timeout-secs` | 60 | Ceiling on a send's timeout; a request asking for more (or none) gets this. | -| `--rate-limit-per-minute` | 120 | Sends per client IP per minute; 0 disables. | -| `--max-concurrent` | 256 | Sends in flight at once. | -| `--trust-forwarded-for` | off | Take the client IP from `X-Forwarded-For`. Only behind a load balancer that sets it. | - -## What it refuses, and why - -A hosted proxy is, by construction, a machine that makes HTTP requests on -behalf of strangers. Left alone that is an open relay into whatever network it -sits on. So it refuses, always, to connect to: - -- loopback (`127/8`, `::1`), private (`10/8`, `172.16/12`, `192.168/16`, - `fc00::/7`), link-local (`169.254/16` — where cloud metadata lives — and - `fe80::/10`), carrier-grade NAT, multicast, reserved and unspecified ranges, - IPv4 addresses carried inside IPv6 forms (`::ffff:a.b.c.d`, the well-known - NAT64 prefix, 6to4), and the whole NAT64 local-use range; -- anything not `http://` or `https://`. - -The check runs **on the resolved addresses, after DNS**, for every hop of a -redirect chain, so a public hostname that points at an internal address is -caught, and so is a `Location:` header that points at one. It also refuses body -types that would read files on the proxy's disk (`binary`, multipart file -fields), since no browser tab could legitimately mean those. - -Refusals are logged with the reason. There is no switch to turn this off: the -proxy's private network is the cloud's, not the user's, so a `localhost` or LAN -API can never be reached through it — that is what the desktop app is for. - -## Deploying - -One binary, no dependencies: - -```shell -cargo build --release -p yaak-send-proxy -YAAK_PROXY_BIND=0.0.0.0:9227 \ -YAAK_PROXY_ALLOWED_ORIGINS=https://yaak.example.com \ -./target/release/yaak-send-proxy -``` - -There is no authentication: an instance is anonymous and protected by the -per-client rate limit and the destination policy, which is what the hosted -funnel wants. Anything more (a shared token, per-user quotas) is a later slice -and would sit in front of `send_http` in `main.rs`. Put TLS in front of it (a -reverse proxy). If the reverse proxy buffers responses, tell it not to: the reply -is a stream and the `X-Accel-Buffering: no` header it sets is honoured by -nginx-shaped ones. - -## The wire - -`POST /v1/http/send` with a JSON body: - -```json -{ - "request": { "url": "https://…", "method": "GET", "headers": […], "body": {…}, "bodyType": null, "urlParameters": […] }, - "settings": { "validateCertificates": true, "followRedirects": true, "timeoutMs": 0, "sendCookies": true, "storeCookies": true }, - "cookies": [ … ] -} -``` - -`request` is a Yaak `HttpRequest` in the desktop's own model shape with every -template already rendered by the tab; the proxy builds the URL, headers and -body from it exactly the way the desktop does after rendering. `cookies` is the -jar's contents (or `null` for no jar). - -The reply is `application/x-ndjson`, one JSON frame per line, in the order things -happened: - -| `type` | When | Carries | -| --- | --- | --- | -| `event` | as the engine produces them | one timeline event, in the desktop's `http_response_event.event` shape | -| `response` | once, when the final hop's headers arrive | status, all headers, request headers as sent, remote address, HTTP version, timing | -| `body` | as the body is read | a decompressed chunk, base64 | -| `done` | last, on success | elapsed, byte counts, and the cookie jar as the send left it | -| `error` | last, on failure | the reason, and any cookies collected before the failure | - -Refusals that happen before anything is sent (a blocked destination, a bad body, -rate limit, capacity) are plain HTTP errors (`403`, `400`, `429`, `503`) with -`{"error": "…"}`, not streams. - -Why a streamed HTTP response and not a WebSocket: one `POST` is stateless by -construction, cancellable by closing the connection, readable with `curl`, and -needs no upgrade handling on either side. A WebSocket only earns its keep when -traffic is bidirectional, which a single send is not. - -The TypeScript side of this contract is generated from `src/wire.rs` by ts-rs -into `bindings/` (run `cargo test -p yaak-send-proxy` after changing a frame) -and published to the tab as `@yaakapp-internal/send-proxy`, so a change to the -wire on one side is a type error on the other. - -`GET /v1/health` reports the version and the effective limits. - -## What comes later - -Not built, by design, but the router is shaped for it: a WebSocket relay -(`/v1/ws/relay`) and a gRPC relay (`/v1/grpc/relay`) would be long-lived, -bidirectional endpoints on the same binary, behind the same destination policy -and limits. They differ from this endpoint in holding per-connection -in-memory state while a connection is open (never persisted), which brings -connection limits and a larger abuse surface — the reason they are separate -work. diff --git a/crates-server/yaak-send-proxy/index.ts b/crates-server/yaak-send-proxy/index.ts deleted file mode 100644 index e9fdd9db..00000000 --- a/crates-server/yaak-send-proxy/index.ts +++ /dev/null @@ -1,4 +0,0 @@ -// The send proxy's wire contract, generated by ts-rs from src/wire.rs -// (`cargo test -p yaak-send-proxy`). The tab imports these so a change to a -// frame on the Rust side is a type error in packages/platform/src/web. -export type { Frame, SendRequest } from "./bindings/gen_send_proxy"; diff --git a/crates-server/yaak-send-proxy/src/config.rs b/crates-server/yaak-send-proxy/src/config.rs deleted file mode 100644 index 91ae2ccd..00000000 --- a/crates-server/yaak-send-proxy/src/config.rs +++ /dev/null @@ -1,52 +0,0 @@ -use clap::Parser; -use std::net::SocketAddr; - -/// A stateless HTTP send executor for Yaak running in a browser. -/// -/// The tab renders the request and owns the data; this binary only puts bytes on the -/// network and streams back what came back. Nothing is written to disk or a database. -#[derive(Parser, Debug, Clone)] -#[command(name = "yaak-send-proxy", version, about, long_about = None)] -pub struct Config { - /// Address to listen on. 127.0.0.1 for a local instance; 0.0.0.0 inside a container. - #[arg(long, env = "YAAK_PROXY_BIND", default_value = "127.0.0.1:9227")] - pub bind: SocketAddr, - - /// Browser origins allowed to call this proxy (CORS), comma-separated. `*` allows any. - /// A local dev instance wants the Vite origin; a hosted instance wants its own web origin. - #[arg( - long, - env = "YAAK_PROXY_ALLOWED_ORIGINS", - default_value = "*", - value_delimiter = ',' - )] - pub allowed_origins: Vec, - - /// Largest request the proxy accepts from the tab (the rendered request JSON, body included). - #[arg(long, env = "YAAK_PROXY_MAX_REQUEST_BYTES", default_value_t = 16 * 1024 * 1024)] - pub max_request_bytes: usize, - - /// Largest upstream response body the proxy will relay before cutting the send off. - #[arg(long, env = "YAAK_PROXY_MAX_RESPONSE_BYTES", default_value_t = 64 * 1024 * 1024)] - pub max_response_bytes: usize, - - /// Ceiling on a send's timeout, in seconds. A request asking for longer (or for no timeout) - /// gets this instead. - #[arg(long, env = "YAAK_PROXY_MAX_TIMEOUT_SECS", default_value_t = 60)] - pub max_timeout_secs: u64, - - /// Sends allowed per client IP per minute. 0 disables the limit. This and the concurrency - /// cap are the whole of what protects an instance: there is no authentication. - #[arg(long, env = "YAAK_PROXY_RATE_LIMIT_PER_MINUTE", default_value_t = 120)] - pub rate_limit_per_minute: u32, - - /// Sends in flight at once across all clients. - #[arg(long, env = "YAAK_PROXY_MAX_CONCURRENT", default_value_t = 256)] - pub max_concurrent: usize, - - /// Take the client IP from `X-Forwarded-For` (first hop) instead of the socket. Only turn - /// this on behind a load balancer that sets the header; otherwise anyone can spoof their way - /// past the rate limit. - #[arg(long, env = "YAAK_PROXY_TRUST_FORWARDED_FOR", default_value_t = false)] - pub trust_forwarded_for: bool, -} diff --git a/crates-server/yaak-send-proxy/Cargo.toml b/crates-server/yaak-web/Cargo.toml similarity index 82% rename from crates-server/yaak-send-proxy/Cargo.toml rename to crates-server/yaak-web/Cargo.toml index 0b525048..024b1674 100644 --- a/crates-server/yaak-send-proxy/Cargo.toml +++ b/crates-server/yaak-web/Cargo.toml @@ -1,9 +1,9 @@ [package] -name = "yaak-send-proxy" +name = "yaak-web" version = "0.1.0" edition = "2024" publish = false -description = "Stateless HTTP send executor for Yaak in the browser" +description = "The server behind Yaak in the browser: executes sends, and can serve the app" # The send engine (yaak-http) and the model types it speaks (yaak-models, for # HttpRequest / Cookie / HttpResponseEventData). Deliberately NOT yaak (the @@ -13,7 +13,7 @@ description = "Stateless HTTP send executor for Yaak in the browser" # its query layer. [[bin]] -name = "yaak-send-proxy" +name = "yaak-web" path = "src/main.rs" [dependencies] @@ -28,7 +28,7 @@ log = { workspace = true } serde = { workspace = true, features = ["derive"] } serde_json = { workspace = true } tokio = { workspace = true, features = ["rt-multi-thread", "macros", "signal", "sync", "io-util", "time", "net"] } -tower-http = { version = "0.6", features = ["cors"] } +tower-http = { version = "0.6", features = ["compression-gzip", "compression-zstd", "cors", "fs"] } ts-rs = { workspace = true } url = "2" uuid = { version = "1", features = ["v4"] } diff --git a/crates-server/yaak-web/README.md b/crates-server/yaak-web/README.md new file mode 100644 index 00000000..c30e9beb --- /dev/null +++ b/crates-server/yaak-web/README.md @@ -0,0 +1,219 @@ +# yaak-web + +The network half of Yaak in a browser — and, with `--serve`, the half that +hands the browser the app in the first place. + +A tab can't see an HTTP response the way a desktop app can: CORS hides most +headers (2 of 8 in a typical response), redirects are followed silently, and +there is no timeline. So the tab renders the request and posts it here, and this +process puts it on the network with the desktop's own engine (`yaak-http`) and +streams back everything that happened — every header, every redirect hop, DNS +timing, the body — for the tab to store. + +It is a **stateless executor**. It keeps nothing: no database, no files, no +sessions, no cookies between calls. Every byte it sees comes from the tab in the +request, and every byte it returns is stored by the tab. Restart it any time. + +## Self-hosting it + +One container, no configuration, nothing behind it: + +```shell +docker run -p 8080:8080 ghcr.io/mountain-loop/yaak-web +``` + +Open . The image carries the built web client and this +binary, which serves it — so the app and its sends are on one origin, and the +tab's send URL is a path (`/v1/http/send`) rather than an address anyone has to +configure. The image is `linux/amd64` and `linux/arm64`, built from +`Dockerfile.web` at the repo root. + +Your data lives in your browser (SQLite compiled to wasm, in IndexedDB), not in +the container. The container is stateless: nothing is written to disk, so +upgrading is `docker pull` and nothing else. + +Two settings are worth knowing about: + +```shell +docker run -p 8080:8080 \ + -e YAAK_WEB_ALLOW_PRIVATE_NETWORKS=true \ + -e YAAK_WEB_RATE_LIMIT_PER_MINUTE=0 \ + ghcr.io/mountain-loop/yaak-web +``` + +- **`YAAK_WEB_ALLOW_PRIVATE_NETWORKS=true`** lets sends reach loopback, + private and link-local addresses. Off by default, and it should stay off on + anything strangers can reach — see [What it refuses](#what-it-refuses-and-why). + Turn it on for an instance on your own network, where calling the API on the + next machine is the whole point. Note that "private" is relative to the + *container*: `127.0.0.1` is the container itself, and reaching the Docker + host means `host.docker.internal` (or `--network host`). +- **`YAAK_WEB_RATE_LIMIT_PER_MINUTE`** defaults to 120 sends per client IP, + which suits a public instance and not a team of your own; `0` disables it. + +Behind a reverse proxy, add `YAAK_WEB_TRUST_FORWARDED_FOR=true` so the rate +limit sees real client addresses instead of its own — and only then, since +otherwise anyone can spoof the header. If the reverse proxy buffers responses, +tell it not to: sends are streamed, and the `X-Accel-Buffering: no` header this +binary sets is honoured by nginx-shaped ones. + +## Running it from source + +```shell +cargo run -p yaak-web -- --serve dist/apps/yaak-client +``` + +after a `YAAK_TARGET=web SKIP_WASM_BUILD=1 npx vp -C apps/yaak-client build`. +Without `--serve` it is the send executor alone, which is what the frontend +dev server wants: + +```shell +cargo run -p yaak-web +YAAK_TARGET=web npm run dev --workspace @yaakapp/yaak-client +``` + +A dev build looks for the server at `http://127.0.0.1:9227` (the Vite server is a +different origin and serves no `/v1`); a production build sends to its own +origin unless `VITE_YAAK_WEB_URL` was set when it was built. + +## Configuration + +Every flag has a `YAAK_WEB_*` environment variable, so a container needs no +arguments; `--help` lists them all. + +| Flag | Default | What | +| --- | --- | --- | +| `--serve` | off | Also serve a built web client from this directory, on the same origin. | +| `--bind` | `127.0.0.1:9227` | Listen address. The image sets `0.0.0.0:8080`. | +| `--allow-private-networks` | off | Allow sends to loopback, private and link-local addresses. | +| `--allowed-origins` | `*` | CORS origins, comma-separated. Unused when the app is served from here: same origin, no CORS. | +| `--max-request-bytes` | 16 MiB | Largest rendered request accepted from the tab. | +| `--max-response-bytes` | 64 MiB | Largest upstream body relayed before the send is cut off. | +| `--max-timeout-secs` | 60 | Ceiling on a send's timeout; a request asking for more (or none) gets this. | +| `--rate-limit-per-minute` | 120 | Sends per client IP per minute; 0 disables. | +| `--max-concurrent` | 256 | Sends in flight at once. | +| `--trust-forwarded-for` | off | Take the client IP from `X-Forwarded-For`. Only behind a load balancer that sets it. | + +## Serving the app + +`--serve DIR` puts a file server behind the API routes: `/v1/*` is matched +first, everything else comes from `DIR`, and a path with no file behind it gets +`index.html` so the app's own routes survive a refresh. Responses are compressed +(gzip or zstd) on the fly. `/assets/*` is cached forever — Vite content-hashes +those names — and everything else is `no-cache`, so a new deploy arrives on the +next reload. + +Serving files changes nothing about sending: the same rendered request, the same +destination policy, the same stateless executor. It exists so that a +self-hosted Yaak is one thing to run rather than two. + +## Split deployments + +The app and the sender can still be separate services — one CDN-hosted bundle and +one server elsewhere, or one server shared by several fronts. Then the bundle has +to be told where to send, at build time: + +```shell +docker build -f Dockerfile.web \ + --build-arg VITE_YAAK_WEB_URL=https://send.example.com . +``` + +and the server needs the CORS origins its callers use, since the requests are no +longer same-origin: + +```shell +docker run -p 8080:8080 \ + -e YAAK_WEB_ALLOWED_ORIGINS=https://yaak.example.com \ + ghcr.io/mountain-loop/yaak-web \ + yaak-web +``` + +The trailing `yaak-web` is a command override: the same image run without +`--serve`, so it executes sends and serves no app. + +## What it refuses, and why + +A hosted sender is, by construction, a machine that makes HTTP requests on +behalf of strangers. Left alone that is an open relay into whatever network it +sits on. So by default it refuses to connect to: + +- loopback (`127/8`, `::1`), private (`10/8`, `172.16/12`, `192.168/16`, + `fc00::/7`), link-local (`169.254/16` — where cloud metadata lives — and + `fe80::/10`), carrier-grade NAT, multicast, reserved and unspecified ranges, + IPv4 addresses carried inside IPv6 forms (`::ffff:a.b.c.d`, the well-known + NAT64 prefix, 6to4), and the whole NAT64 local-use range; +- anything not `http://` or `https://`. + +The check runs **on the resolved addresses, after DNS**, for every hop of a +redirect chain, so a public hostname that points at an internal address is +caught, and so is a `Location:` header that points at one. It also refuses body +types that would read files on its own disk (`binary`, multipart file +fields), since no browser tab could legitimately mean those. + +Refusals are logged with the reason. On a public instance (`web.yaak.app`, or +anything else strangers can reach) this must stay on: the machine's private +network is the host's, not the user's, so a `localhost` or LAN API is not the +user's to reach through it — the desktop app is what reaches those. On an +instance you run for yourself, that reasoning is inverted, and +`--allow-private-networks` inverts the policy with it. It allows every range +above, including `169.254.169.254`, so use it only where the network on the +other side is one the users are entitled to. + +There is no authentication either way: an instance is anonymous, protected by +the per-client rate limit and the destination policy. Anything more (a shared +token, per-user quotas) is a later slice and would sit in front of `send_http` +in `main.rs`. Put TLS in front of a public instance. + +## The wire + +`POST /v1/http/send` with a JSON body: + +```json +{ + "request": { "url": "https://…", "method": "GET", "headers": […], "body": {…}, "bodyType": null, "urlParameters": […] }, + "settings": { "validateCertificates": true, "followRedirects": true, "timeoutMs": 0, "sendCookies": true, "storeCookies": true }, + "cookies": [ … ] +} +``` + +`request` is a Yaak `HttpRequest` in the desktop's own model shape with every +template already rendered by the tab; the server builds the URL, headers and +body from it exactly the way the desktop does after rendering. `cookies` is the +jar's contents (or `null` for no jar). + +The reply is `application/x-ndjson`, one JSON frame per line, in the order things +happened: + +| `type` | When | Carries | +| --- | --- | --- | +| `event` | as the engine produces them | one timeline event, in the desktop's `http_response_event.event` shape | +| `response` | once, when the final hop's headers arrive | status, all headers, request headers as sent, remote address, HTTP version, timing | +| `body` | as the body is read | a decompressed chunk, base64 | +| `done` | last, on success | elapsed, byte counts, and the cookie jar as the send left it | +| `error` | last, on failure | the reason, and any cookies collected before the failure | + +Refusals that happen before anything is sent (a blocked destination, a bad body, +rate limit, capacity) are plain HTTP errors (`403`, `400`, `429`, `503`) with +`{"error": "…"}`, not streams. + +Why a streamed HTTP response and not a WebSocket: one `POST` is stateless by +construction, cancellable by closing the connection, readable with `curl`, and +needs no upgrade handling on either side. A WebSocket only earns its keep when +traffic is bidirectional, which a single send is not. + +The TypeScript side of this contract is generated from `src/wire.rs` by ts-rs +into `bindings/` (run `cargo test -p yaak-web` after changing a frame) +and published to the tab as `@yaakapp-internal/web`, so a change to the +wire on one side is a type error on the other. + +`GET /v1/health` reports the version and the effective limits. + +## What comes later + +Not built, by design, but the router is shaped for it: a WebSocket relay +(`/v1/ws/relay`) and a gRPC relay (`/v1/grpc/relay`) would be long-lived, +bidirectional endpoints on the same binary, behind the same destination policy +and limits. They differ from this endpoint in holding per-connection +in-memory state while a connection is open (never persisted), which brings +connection limits and a larger abuse surface — the reason they are separate +work. diff --git a/crates-server/yaak-send-proxy/bindings/gen_models.ts b/crates-server/yaak-web/bindings/gen_models.ts similarity index 97% rename from crates-server/yaak-send-proxy/bindings/gen_models.ts rename to crates-server/yaak-web/bindings/gen_models.ts index 7c3f7a84..2263c04a 100644 --- a/crates-server/yaak-send-proxy/bindings/gen_models.ts +++ b/crates-server/yaak-web/bindings/gen_models.ts @@ -28,7 +28,7 @@ export type HttpResponseHeader = { name: string, value: string, }; /** * The resolved send settings, values only: what an executor has to obey, with the sources * (which model each came from) left behind in [`ResolvedHttpRequestSettings`]. This is what - * crosses from a tab to the send proxy, and what the proxy reads. + * crosses from a tab to the Yaak server, and what the server reads. */ export type HttpSendSettings = { validateCertificates: boolean, followRedirects: boolean, /** diff --git a/crates-server/yaak-send-proxy/bindings/gen_send_proxy.ts b/crates-server/yaak-web/bindings/gen_web.ts similarity index 93% rename from crates-server/yaak-send-proxy/bindings/gen_send_proxy.ts rename to crates-server/yaak-web/bindings/gen_web.ts index 3132405f..4361472b 100644 --- a/crates-server/yaak-send-proxy/bindings/gen_send_proxy.ts +++ b/crates-server/yaak-web/bindings/gen_web.ts @@ -49,13 +49,13 @@ cookies: Array | null, } | { "type": "error", message: string, cookies: export type SendRequest = { /** * The request to send, in the desktop's own model shape but with every template already - * rendered by the tab. The proxy builds the URL, headers and body from it exactly the way + * rendered by the tab. The server builds the URL, headers and body from it exactly the way * the desktop does after rendering. */ request: HttpRequest, /** * The resolved settings, values only. Where they came from is the tab's to record in - * its timeline; the proxy only needs to obey them. + * its timeline; the server only needs to obey them. */ settings: HttpSendSettings, /** diff --git a/crates-server/yaak-web/index.ts b/crates-server/yaak-web/index.ts new file mode 100644 index 00000000..62ebb54e --- /dev/null +++ b/crates-server/yaak-web/index.ts @@ -0,0 +1,4 @@ +// The server's wire contract, generated by ts-rs from src/wire.rs +// (`cargo test -p yaak-web`). The tab imports these so a change to a +// frame on the Rust side is a type error in packages/platform/src/web. +export type { Frame, SendRequest } from "./bindings/gen_web"; diff --git a/crates-server/yaak-send-proxy/package.json b/crates-server/yaak-web/package.json similarity index 61% rename from crates-server/yaak-send-proxy/package.json rename to crates-server/yaak-web/package.json index cc290995..60cadb82 100644 --- a/crates-server/yaak-send-proxy/package.json +++ b/crates-server/yaak-web/package.json @@ -1,5 +1,5 @@ { - "name": "@yaakapp-internal/send-proxy", + "name": "@yaakapp-internal/web", "version": "1.0.0", "private": true, "main": "index.ts" diff --git a/crates-server/yaak-web/src/config.rs b/crates-server/yaak-web/src/config.rs new file mode 100644 index 00000000..bd86c82f --- /dev/null +++ b/crates-server/yaak-web/src/config.rs @@ -0,0 +1,67 @@ +use clap::Parser; +use std::net::SocketAddr; +use std::path::PathBuf; + +/// The server behind Yaak running in a browser. +/// +/// The tab renders the request and owns the data; this binary puts the bytes on the network +/// and streams back what came back, and with `--serve` hands the browser the app as well. +/// Nothing is written to disk or a database. +#[derive(Parser, Debug, Clone)] +#[command(name = "yaak-web", version, about, long_about = None)] +pub struct Config { + /// Address to listen on. 127.0.0.1 for a local instance; 0.0.0.0 inside a container. + #[arg(long, env = "YAAK_WEB_BIND", default_value = "127.0.0.1:9227")] + pub bind: SocketAddr, + + /// Also serve a built web client from this directory, on the same origin as the API. + /// Unknown paths fall back to `index.html` so the app's own routes work on a refresh. + /// Without this the binary is only the send executor. + #[arg(long, env = "YAAK_WEB_SERVE", value_name = "DIR")] + pub serve: Option, + + /// Allow sends to loopback, private and link-local addresses. Off by default, because a + /// server reachable by strangers is an open relay into the network it sits on. Turn it on + /// only for an instance whose users are meant to reach that network — a self-hosted one + /// on a LAN, where the point is to call the API on the next machine. + #[arg(long, env = "YAAK_WEB_ALLOW_PRIVATE_NETWORKS", default_value_t = false)] + pub allow_private_networks: bool, + + /// Browser origins allowed to call this server (CORS), comma-separated. `*` allows any. + /// A local dev instance wants the Vite origin; a hosted instance wants its own web origin. + #[arg( + long, + env = "YAAK_WEB_ALLOWED_ORIGINS", + default_value = "*", + value_delimiter = ',' + )] + pub allowed_origins: Vec, + + /// Largest request the server accepts from the tab (the rendered request JSON, body included). + #[arg(long, env = "YAAK_WEB_MAX_REQUEST_BYTES", default_value_t = 16 * 1024 * 1024)] + pub max_request_bytes: usize, + + /// Largest upstream response body the server will relay before cutting the send off. + #[arg(long, env = "YAAK_WEB_MAX_RESPONSE_BYTES", default_value_t = 64 * 1024 * 1024)] + pub max_response_bytes: usize, + + /// Ceiling on a send's timeout, in seconds. A request asking for longer (or for no timeout) + /// gets this instead. + #[arg(long, env = "YAAK_WEB_MAX_TIMEOUT_SECS", default_value_t = 60)] + pub max_timeout_secs: u64, + + /// Sends allowed per client IP per minute. 0 disables the limit. This and the concurrency + /// cap are the whole of what protects an instance: there is no authentication. + #[arg(long, env = "YAAK_WEB_RATE_LIMIT_PER_MINUTE", default_value_t = 120)] + pub rate_limit_per_minute: u32, + + /// Sends in flight at once across all clients. + #[arg(long, env = "YAAK_WEB_MAX_CONCURRENT", default_value_t = 256)] + pub max_concurrent: usize, + + /// Take the client IP from `X-Forwarded-For` (first hop) instead of the socket. Only turn + /// this on behind a load balancer that sets the header; otherwise anyone can spoof their way + /// past the rate limit. + #[arg(long, env = "YAAK_WEB_TRUST_FORWARDED_FOR", default_value_t = false)] + pub trust_forwarded_for: bool, +} diff --git a/crates-server/yaak-send-proxy/src/guard.rs b/crates-server/yaak-web/src/guard.rs similarity index 89% rename from crates-server/yaak-send-proxy/src/guard.rs rename to crates-server/yaak-web/src/guard.rs index b94604d7..284fb7a1 100644 --- a/crates-server/yaak-send-proxy/src/guard.rs +++ b/crates-server/yaak-web/src/guard.rs @@ -20,13 +20,20 @@ use yaak_http::dns::AddressFilter; use yaak_http::sender::{HttpResponse, HttpResponseEvent, HttpSender}; use yaak_http::types::SendableHttpRequest; -/// The destination policy, shared by every send: public addresses only, always. A hosted -/// proxy's "private network" is the cloud's, not the user's, so there is no configuration -/// that makes reaching it right. +/// The destination policy, shared by every send: public addresses only, unless the operator +/// has said otherwise. A hosted server's "private network" is the cloud's, not the user's, so +/// the default is public-only; a self-hosted instance on a LAN can be told that its private +/// network *is* the user's, which is what `--allow-private-networks` means. #[derive(Clone, Default)] -pub struct DestinationPolicy; +pub struct DestinationPolicy { + allow_private: bool, +} impl DestinationPolicy { + pub fn new(allow_private: bool) -> Self { + Self { allow_private } + } + /// Check a URL before a hop is attempted: scheme and literal IPs. A hostname that passes /// here still has its resolved addresses checked by [`Self::address_filter`]. pub fn check_url(&self, raw: &str) -> Result<(), String> { @@ -53,9 +60,12 @@ impl DestinationPolicy { } pub fn check_ip(&self, ip: IpAddr) -> Result<(), String> { + if self.allow_private { + return Ok(()); + } match non_public_reason(ip) { Some(reason) => Err(format!( - "Refusing to connect to {ip}: {reason}. This proxy only sends to public addresses" + "Refusing to connect to {ip}: {reason}. This server only sends to public addresses" )), None => Ok(()), } @@ -236,15 +246,24 @@ mod tests { #[test] fn literal_private_addresses_in_urls_are_refused() { - let policy = DestinationPolicy; + let policy = DestinationPolicy::new(false); assert!(policy.check_url("http://127.0.0.1/").is_err()); assert!(policy.check_url("http://[::1]/").is_err()); assert!(policy.check_url("http://169.254.169.254/latest/meta-data").is_err()); } + #[test] + fn allow_private_networks_opens_the_local_ranges_but_not_other_schemes() { + let policy = DestinationPolicy::new(true); + assert!(policy.check_url("http://127.0.0.1/").is_ok()); + assert!(policy.check_ip(ip("10.0.0.1")).is_ok()); + assert!(policy.check_ip(ip("169.254.169.254")).is_ok()); + assert!(policy.check_url("file:///etc/passwd").is_err()); + } + #[test] fn only_http_schemes() { - let policy = DestinationPolicy; + let policy = DestinationPolicy::new(false); assert!(policy.check_url("ftp://example.com/").is_err()); assert!(policy.check_url("file:///etc/passwd").is_err()); assert!(policy.check_url("https://example.com/").is_ok()); diff --git a/crates-server/yaak-send-proxy/src/limits.rs b/crates-server/yaak-web/src/limits.rs similarity index 100% rename from crates-server/yaak-send-proxy/src/limits.rs rename to crates-server/yaak-web/src/limits.rs diff --git a/crates-server/yaak-send-proxy/src/main.rs b/crates-server/yaak-web/src/main.rs similarity index 69% rename from crates-server/yaak-send-proxy/src/main.rs rename to crates-server/yaak-web/src/main.rs index 4db927f2..edf9c078 100644 --- a/crates-server/yaak-send-proxy/src/main.rs +++ b/crates-server/yaak-web/src/main.rs @@ -1,4 +1,4 @@ -//! yaak-send-proxy: the network half of Yaak in a browser. +//! yaak-web: the network half of Yaak in a browser. //! //! A tab can't see a response the way a desktop app can — CORS hides most //! headers, redirects are followed silently, there is no timeline. So the tab @@ -6,7 +6,7 @@ //! with the desktop's own engine and streams back everything that happened, //! for the tab to store. It keeps nothing: no database, no files, no session. //! -//! One binary, configured by flags or `YAAK_PROXY_*` environment variables. +//! One binary, configured by flags or `YAAK_WEB_*` environment variables. //! See README.md for running and deploying it, and `guard.rs` for what it //! refuses to talk to. @@ -18,8 +18,9 @@ mod wire; use axum::Router; use axum::body::Body; -use axum::extract::{ConnectInfo, DefaultBodyLimit, State}; +use axum::extract::{ConnectInfo, DefaultBodyLimit, Request, State}; use axum::http::{HeaderMap, HeaderValue, Method, StatusCode, header}; +use axum::middleware::{self, Next}; use axum::response::{IntoResponse, Json, Response}; use axum::routing::{get, post}; use clap::Parser; @@ -30,10 +31,13 @@ use log::{info, warn}; use send::{Refusal, SendLimits}; use serde_json::json; use std::net::{IpAddr, SocketAddr}; +use std::path::Path; use std::sync::Arc; use std::time::{Duration, Instant}; use tokio::sync::Semaphore; +use tower_http::compression::CompressionLayer; use tower_http::cors::{AllowOrigin, CorsLayer}; +use tower_http::services::{ServeDir, ServeFile}; use wire::SendRequest; #[derive(Clone)] @@ -49,7 +53,13 @@ async fn main() { env_logger::Builder::from_env(env_logger::Env::default().default_filter_or("info")).init(); let config = Config::parse(); - let policy = DestinationPolicy; + let policy = DestinationPolicy::new(config.allow_private_networks); + if config.allow_private_networks { + warn!( + "Sends to loopback, private and link-local addresses are ALLOWED. Only run this way \ + on an instance strangers cannot reach" + ); + } let state = AppState { limits: Arc::new(SendLimits { policy, @@ -66,7 +76,7 @@ async fn main() { .allow_headers([header::CONTENT_TYPE]) .allow_origin(allowed_origins(&state.config.allowed_origins)); - let app = Router::new() + let api = Router::new() .route("/v1/health", get(health)) // A WebSocket or gRPC relay would sit beside this as `/v1/ws/relay` and `/v1/grpc/relay` // on the same router, behind the same policy, limits and auth. Not built; see README. @@ -75,13 +85,21 @@ async fn main() { .layer(cors) .with_state(state.clone()); + let app = match &state.config.serve { + Some(dir) => { + info!("Serving the web client from {}", dir.display()); + api.merge(web_router(dir)) + } + None => api, + }; + let bind = state.config.bind; let listener = tokio::net::TcpListener::bind(bind).await.unwrap_or_else(|e| { eprintln!("Failed to bind {bind}: {e}"); std::process::exit(1); }); info!( - "yaak-send-proxy listening on http://{bind} (rate limit: {}/min)", + "yaak-web listening on http://{bind} (rate limit: {}/min)", state.config.rate_limit_per_minute, ); @@ -94,6 +112,48 @@ async fn main() { .expect("server error"); } +/// The built web client, served on the same origin as the API. +/// +/// This is what makes a single container zero-configuration: the tab's send URL is a path on +/// the page's own origin, so there is no CORS, no second service and no URL to bake in. It is +/// only a file server — a send behaves exactly as it does without this flag. +/// +/// Merged as a fallback, so the `/v1` routes are matched first and a request that matches no +/// file at all gets `index.html` (the app routes client-side; a deep link must survive a +/// refresh). +fn web_router(dir: &Path) -> Router { + let index = ServeFile::new(dir.join("index.html")); + Router::new() + // `fallback`, not `not_found_service`: the app's own routes are real pages, so + // index.html is served with the 200 the browser expects, not a 404 carrying HTML. + .fallback_service(ServeDir::new(dir).fallback(index)) + .layer(middleware::from_fn(cache_control)) + .layer(CompressionLayer::new()) +} + +/// Vite gives everything in `/assets` a content-hashed name, so those can be cached forever. +/// Everything else — `index.html` above all, including the copy served for an unknown path — +/// must be revalidated, or a browser keeps serving the deploy before last. +async fn cache_control(req: Request, next: Next) -> Response { + let hashed_name = req.uri().path().starts_with("/assets/"); + let mut res = next.run(req).await; + if !res.status().is_success() { + return res; + } + let is_html = res + .headers() + .get(header::CONTENT_TYPE) + .and_then(|v| v.to_str().ok()) + .is_some_and(|v| v.starts_with("text/html")); + let value = if hashed_name && !is_html { + "public, max-age=31536000, immutable" + } else { + "no-cache" + }; + res.headers_mut().insert(header::CACHE_CONTROL, HeaderValue::from_static(value)); + res +} + fn allowed_origins(origins: &[String]) -> AllowOrigin { if origins.iter().any(|o| o.trim() == "*") { return AllowOrigin::any(); @@ -149,7 +209,7 @@ async fn send_http( let Ok(permit) = state.in_flight.clone().try_acquire_owned() else { warn!("At capacity; refusing {ip}"); - return error_response(StatusCode::SERVICE_UNAVAILABLE, "This proxy is at capacity"); + return error_response(StatusCode::SERVICE_UNAVAILABLE, "This server is at capacity"); }; let prepared = match send::prepare(state.limits.clone(), body).await { diff --git a/crates-server/yaak-send-proxy/src/send.rs b/crates-server/yaak-web/src/send.rs similarity index 96% rename from crates-server/yaak-send-proxy/src/send.rs rename to crates-server/yaak-web/src/send.rs index a8c2c980..814b06d8 100644 --- a/crates-server/yaak-send-proxy/src/send.rs +++ b/crates-server/yaak-web/src/send.rs @@ -42,7 +42,7 @@ pub struct SendLimits { pub enum Refusal { /// The request asks for something a browser-originated send cannot mean. Unsupported(String), - /// The destination is not one this proxy will talk to. + /// The destination is not one this server will talk to. Destination(String), /// The request could not be turned into something sendable. Invalid(String), @@ -57,10 +57,10 @@ pub async fn prepare(limits: Arc, send: SendRequest) -> Result, send: SendRequest) -> Result limits.max_response_bytes { break Err(format!( - "Response body exceeds this proxy's limit of {} bytes", + "Response body exceeds this server's limit of {} bytes", limits.max_response_bytes )); } @@ -309,7 +309,7 @@ impl PreparedSend { /// /// A connection error from reqwest arrives wrapped several layers deep, and the layer that /// says something useful — "Refusing to connect to ::1: loopback" — is the innermost. The -/// desktop shows the outer `Debug`; a stranger reading a proxy's reply deserves the reason. +/// desktop shows the outer `Debug`; a stranger reading its reply deserves the reason. fn describe_error(err: &yaak_http::error::Error) -> String { match err { yaak_http::error::Error::Client(e) => { diff --git a/crates-server/yaak-send-proxy/src/wire.rs b/crates-server/yaak-web/src/wire.rs similarity index 89% rename from crates-server/yaak-send-proxy/src/wire.rs rename to crates-server/yaak-web/src/wire.rs index 30eeb584..25561731 100644 --- a/crates-server/yaak-send-proxy/src/wire.rs +++ b/crates-server/yaak-web/src/wire.rs @@ -1,4 +1,4 @@ -//! What crosses the wire between a tab and this proxy. +//! What crosses the wire between a tab and this server. //! //! One `POST /v1/http/send` carries a request the tab has already rendered — //! templates resolved, inheritance applied — plus the send settings and the @@ -6,13 +6,13 @@ //! JSON frames: timeline events as they happen, the response head as soon as //! headers arrive, body chunks as they are read, and one terminal frame. //! -//! Nothing here names a workspace, a request id, or a response id. The proxy +//! Nothing here names a workspace, a request id, or a response id. The server //! does not know what the tab will call this response; it only knows what came //! back. //! //! The TypeScript side of this contract is generated from these types into -//! `bindings/` (`cargo test -p yaak-send-proxy`) and published to the tab as -//! `@yaakapp-internal/send-proxy`, so a change here is a type error there. +//! `bindings/` (`cargo test -p yaak-web`) and published to the tab as +//! `@yaakapp-internal/web`, so a change here is a type error there. use serde::{Deserialize, Serialize}; use ts_rs::TS; @@ -23,14 +23,14 @@ use yaak_models::models::{ /// The body of `POST /v1/http/send`. #[derive(Deserialize, Debug, TS)] #[serde(rename_all = "camelCase")] -#[ts(export, export_to = "gen_send_proxy.ts")] +#[ts(export, export_to = "gen_web.ts")] pub struct SendRequest { /// The request to send, in the desktop's own model shape but with every template already - /// rendered by the tab. The proxy builds the URL, headers and body from it exactly the way + /// rendered by the tab. The server builds the URL, headers and body from it exactly the way /// the desktop does after rendering. pub request: HttpRequest, /// The resolved settings, values only. Where they came from is the tab's to record in - /// its timeline; the proxy only needs to obey them. + /// its timeline; the server only needs to obey them. pub settings: HttpSendSettings, /// The cookies to start with. `None` means no jar at all: nothing sent, nothing kept. #[serde(default)] @@ -45,7 +45,7 @@ pub struct SendRequest { rename_all = "snake_case", rename_all_fields = "camelCase" )] -#[ts(export, export_to = "gen_send_proxy.ts")] +#[ts(export, export_to = "gen_web.ts")] pub enum Frame { /// A timeline event, in the same shape the desktop stores. Interleaved with everything /// else in the order the engine produced it. diff --git a/crates/common/yaak-rpc-schema/bindings/gen_models.ts b/crates/common/yaak-rpc-schema/bindings/gen_models.ts index 78938ae1..9f73f1e7 100644 --- a/crates/common/yaak-rpc-schema/bindings/gen_models.ts +++ b/crates/common/yaak-rpc-schema/bindings/gen_models.ts @@ -73,7 +73,7 @@ export type HttpResponseState = "initialized" | "connected" | "closed"; /** * The resolved send settings, values only: what an executor has to obey, with the sources * (which model each came from) left behind in [`ResolvedHttpRequestSettings`]. This is what - * crosses from a tab to the send proxy, and what the proxy reads. + * crosses from a tab to the Yaak server, and what the server reads. */ export type HttpSendSettings = { validateCertificates: boolean, followRedirects: boolean, /** diff --git a/crates/yaak-models/bindings/gen_models.ts b/crates/yaak-models/bindings/gen_models.ts index 76453e2f..21da46e7 100644 --- a/crates/yaak-models/bindings/gen_models.ts +++ b/crates/yaak-models/bindings/gen_models.ts @@ -307,7 +307,7 @@ export type HttpResponseState = "initialized" | "connected" | "closed"; /** * The resolved send settings, values only: what an executor has to obey, with the sources * (which model each came from) left behind in [`ResolvedHttpRequestSettings`]. This is what - * crosses from a tab to the send proxy, and what the proxy reads. + * crosses from a tab to the Yaak server, and what the server reads. */ export type HttpSendSettings = { validateCertificates: boolean; diff --git a/crates/yaak-models/src/models.rs b/crates/yaak-models/src/models.rs index fdec37cc..98637b03 100644 --- a/crates/yaak-models/src/models.rs +++ b/crates/yaak-models/src/models.rs @@ -197,7 +197,7 @@ impl ResolvedHttpRequestSettings { /// The resolved send settings, values only: what an executor has to obey, with the sources /// (which model each came from) left behind in [`ResolvedHttpRequestSettings`]. This is what -/// crosses from a tab to the send proxy, and what the proxy reads. +/// crosses from a tab to the Yaak server, and what the server reads. #[derive(Debug, Clone, PartialEq, Serialize, Deserialize, TS)] #[serde(rename_all = "camelCase")] #[ts(export, export_to = "gen_models.ts")] diff --git a/crates/yaak-web/Cargo.toml b/crates/yaak-wasm/Cargo.toml similarity index 98% rename from crates/yaak-web/Cargo.toml rename to crates/yaak-wasm/Cargo.toml index 05a0cf1f..32f56137 100644 --- a/crates/yaak-web/Cargo.toml +++ b/crates/yaak-wasm/Cargo.toml @@ -1,5 +1,5 @@ [package] -name = "yaak-web" +name = "yaak-wasm" version = "0.1.0" edition = "2024" publish = false diff --git a/crates/yaak-web/build-wasm.cjs b/crates/yaak-wasm/build-wasm.cjs similarity index 100% rename from crates/yaak-web/build-wasm.cjs rename to crates/yaak-wasm/build-wasm.cjs diff --git a/crates/yaak-web/index.ts b/crates/yaak-wasm/index.ts similarity index 100% rename from crates/yaak-web/index.ts rename to crates/yaak-wasm/index.ts diff --git a/crates/yaak-web/package.json b/crates/yaak-wasm/package.json similarity index 88% rename from crates/yaak-web/package.json rename to crates/yaak-wasm/package.json index 30088d49..da4486a9 100644 --- a/crates/yaak-web/package.json +++ b/crates/yaak-wasm/package.json @@ -1,5 +1,5 @@ { - "name": "@yaakapp-internal/web", + "name": "@yaakapp-internal/wasm", "version": "1.0.0", "private": true, "main": "index.ts", diff --git a/crates/yaak-wasm/pkg/package.json b/crates/yaak-wasm/pkg/package.json new file mode 100644 index 00000000..00e0213a --- /dev/null +++ b/crates/yaak-wasm/pkg/package.json @@ -0,0 +1,17 @@ +{ + "name": "yaak-wasm", + "type": "module", + "version": "0.1.0", + "files": [ + "yaak_wasm_bg.wasm", + "yaak_wasm.js", + "yaak_wasm_bg.js", + "yaak_wasm.d.ts" + ], + "main": "yaak_wasm.js", + "types": "yaak_wasm.d.ts", + "sideEffects": [ + "./yaak_wasm.js", + "./snippets/*" + ] +} \ No newline at end of file diff --git a/crates/yaak-web/pkg/yaak_web.d.ts b/crates/yaak-wasm/pkg/yaak_wasm.d.ts similarity index 98% rename from crates/yaak-web/pkg/yaak_web.d.ts rename to crates/yaak-wasm/pkg/yaak_wasm.d.ts index 42d31de3..19348e8f 100644 --- a/crates/yaak-web/pkg/yaak_web.d.ts +++ b/crates/yaak-wasm/pkg/yaak_wasm.d.ts @@ -29,7 +29,7 @@ export function boot(): Promise; * Resolve and render a request for sending, exactly as the desktop does before it puts the * request on the network: the environment chain, inherited headers and auth, request * settings, the cookie jar. Nothing here touches a socket. What comes back is what the tab - * posts to the send proxy. + * posts to the Yaak server. * * Refuses, with a message the user can act on, when the request needs something this host * doesn't have: an authentication plugin, or a template function. diff --git a/crates/yaak-wasm/pkg/yaak_wasm.js b/crates/yaak-wasm/pkg/yaak_wasm.js new file mode 100644 index 00000000..76f0b2b1 --- /dev/null +++ b/crates/yaak-wasm/pkg/yaak_wasm.js @@ -0,0 +1,9 @@ +/* @ts-self-types="./yaak_wasm.d.ts" */ +import * as wasm from "./yaak_wasm_bg.wasm"; +import { __wbg_set_wasm } from "./yaak_wasm_bg.js"; + +__wbg_set_wasm(wasm); +wasm.__wbindgen_start(); +export { + blob_delete, blob_get, blob_put, boot, prepare_http_send, rpc +} from "./yaak_wasm_bg.js"; diff --git a/crates/yaak-web/pkg/yaak_web_bg.js b/crates/yaak-wasm/pkg/yaak_wasm_bg.js similarity index 99% rename from crates/yaak-web/pkg/yaak_web_bg.js rename to crates/yaak-wasm/pkg/yaak_wasm_bg.js index 2fcf3e7e..8450af8d 100644 --- a/crates/yaak-web/pkg/yaak_web_bg.js +++ b/crates/yaak-wasm/pkg/yaak_wasm_bg.js @@ -66,7 +66,7 @@ export function boot() { * Resolve and render a request for sending, exactly as the desktop does before it puts the * request on the network: the environment chain, inherited headers and auth, request * settings, the cookie jar. Nothing here touches a socket. What comes back is what the tab - * posts to the send proxy. + * posts to the Yaak server. * * Refuses, with a message the user can act on, when the request needs something this host * doesn't have: an authentication plugin, or a template function. @@ -708,7 +708,7 @@ export function __wbindgen_cast_0000000000000002(arg0, arg1) { } export function __wbindgen_cast_0000000000000003(arg0, arg1) { // Cast intrinsic for `Closure(Closure { owned: true, function: Function { arguments: [NamedExternref("IDBVersionChangeEvent")], shim_idx: 83, ret: Result(Unit), inner_ret: Some(Result(Unit)) }, mutable: true }) -> Externref`. - const ret = makeMutClosure(arg0, arg1, wasm_bindgen__convert__closures_____invoke__h38d884a456ef1afe); + const ret = makeMutClosure(arg0, arg1, wasm_bindgen__convert__closures_____invoke__h4381d8e749fe46cf); return ret; } export function __wbindgen_cast_0000000000000004(arg0, arg1) { @@ -765,8 +765,8 @@ function wasm_bindgen__convert__closures_____invoke__ha1c2fa93df0107f3(arg0, arg } } -function wasm_bindgen__convert__closures_____invoke__h38d884a456ef1afe(arg0, arg1, arg2) { - const ret = wasm.wasm_bindgen__convert__closures_____invoke__h38d884a456ef1afe(arg0, arg1, arg2); +function wasm_bindgen__convert__closures_____invoke__h4381d8e749fe46cf(arg0, arg1, arg2) { + const ret = wasm.wasm_bindgen__convert__closures_____invoke__h4381d8e749fe46cf(arg0, arg1, arg2); if (ret[1]) { throw takeFromExternrefTable0(ret[0]); } diff --git a/crates/yaak-web/pkg/yaak_web_bg.wasm b/crates/yaak-wasm/pkg/yaak_wasm_bg.wasm similarity index 85% rename from crates/yaak-web/pkg/yaak_web_bg.wasm rename to crates/yaak-wasm/pkg/yaak_wasm_bg.wasm index c126672732d97837927da11bcab1483149df752c..4828e9e895989e3d3725e97b549f68d4feb12447 100644 GIT binary patch delta 156297 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 Hq`Ukd@=ORB delta 155656 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

Ey2%#R~3=@01}Tw3#EuXwc2Hk zJ|X=qw(+s6UBA+K$SKwxxC?c>ViFaPYCXn;$#VW+EMNH-jISR6O)b3GBG9Oi@naHU2`u{fE} zJK-9lKn?7vb{*7DANeEOd)(EXKYPlRptD{2Y85^k>=Ny>=rJ`Ks0~!k zK0WQ~rf~MhX_whNOxUxvN;HBJKqH7MWap+Do-;1Dxc~>Nh1#c)kpLPQpk`{Q!_T;S zD4hRt#-&EIy|QSPrZo7%n5BbuNUT#bG0=@3cpKM>2`zbhG-0KL)udO~G|V4-!yGnca=Mt4ENj*5=(Qjp4&ZLGP;T{CFD zSghAm1tC{lFXaewAf+5pQBnzMsFur9QivN0JYspigz=V`{V?8lLsLylo@j)m1HA!- z28xK1pb=sTJ|ci20Z394DF6vVK=ZAN9Wc9_)-hWPYC=RpK2Q<~q9#NmWFz%xM7YF5 zQjkU?FkLgnD-acE5vnZ7g`kE(a>3rPxNXtJQUW^0zO=XlH-+_avFJ68@)B_rT`VcC zCP;okpDwz%kTtftlLyIC*{@Tna3Eel0$&p^RYXAQ*D%U^J=qmX2_59s{@mE`aq-M6|e3h$`a11!Cr@EUe?pU`pEh3+#u6UxT+s8jp^)p?`4JGUi-iqBsHz1YGw zzT|c*Mf~bZ?m_zhWDUpBJO+HN`WK(}n*05f4%5NL2cy)5!C`(FK-d~e2|(5gXc>i- zVLbt~fcywnIl^t{BSyG4M}x>dTMc{PK!QTgi(NznGGs( zXRy0JLklJR+0Wd+#D!i!r*1kdULf3@EOJS+UbEasLUw(fx`*&+qKTw+~9L&$*I+#=d%kzcw*FrENhK>GeiZ52z}voMyy#&)@ZH!R=(gzcWkYstW(EI z7mVPfq1i1DZr{7kJuz%@eNA|ECznjJJfYkjqrd~;^Y!lc>9mcEE$+rqi7S?32IvzH zG^gC~k?LB0+fMg;I^{51`m1}6u!x+GZ^qUgai_5pMvsZF*zJB;kFQAG@4g%Soe2g_bLMU`;&UzeiKMv>MIY-<+)T%n-elr#> zHV>V4cgAJvY4`28960Un0PpDRGwunx=vCJ+^W5qgw&I+-W$@Qfe)ya_UYAfgQ7|N6 z(`*ekva1)|SqVEP3WfwASA%WLaS@>16FZW1Rbc(X9=qr^CL9Q1*&6KSqb|B1jZ!{a zbjY*7pesDbz)io;hW+HS@|z<)Q-fZ;(fFSA%Z0WgNOG~buyARCU5@rVh!lQ3V?4%a zwy%ljFZf7$^4Y+~xGQh!c~@7km>oFcPUpRnJROwSH3uQb9)+*SK{hklGX{qbv`+E- z5|6Z?4UL{TumCPKdfKw$-R@SriOFLnLv}l}=N&~ivy9zr_T0y#t)Auy;AKsI&#TF| zQ%G`HT=R`mXB^mYeaO6U55nf8Uc1P)-{txEPU+M}M|+CQ_JS+c4m6|?3z5SfatoY@ z)W0aNJ!SIHbx^^)4^)Td4~@m)Mnvo9cJ)kD>e!>Yck^hGrO<~60~VP_Xp<9x*ur*) zL;=AR?WAr!e?eGo^tFm1baQDpPf#sL`o$W;A^oD<0m&{ig`Ml>8K$WYDJ}iS7lA`* z=|h_2c%F#JSW&&QL4P`*3cP)$PTUzfV-@IOZCk;b-0x|NV2Zo%_jE`fiR>8K z*XlaxJLvF_W<&K#cF+Bu+mdk;EDjZZOf~H+^8rti@-YuQ;8FBJEyFDjdweiyz4ox@ zzL33IgVj9Z`Myy|@rih<(_%*nQ%d6PH}>lIIi?#N1h;S~?gnXDPh&kyh{ z(?u0b!73~@&Y1t2M`26f^mKv=PWgxDNMraR{58UJQZp3_CFV$WsKBF{3dulEXG4Jh zki(*A=M9BBj0sbr2|_}6mv

  • 7OEOW^h=B&5R=C8;DNQvy%m$tlLDSJpBF@GVTzg zB8L4&^K`B>MF!g!+ZWFp>lvSx{(WODKm*3^i$lsN4`2h;4?8vc^=r@5y6T3A3-P71 zs_s#-tg^2+mc2N`^R2RkH=pT=QPM+M=-?*?3%OqKU}))gcIzxp>Y(k!U&HX7xF+l= zy9ua0r7R5o8^K{}haX4XwzNhBJFz9~A;+iy22>RjE-}2|j8?#Yp5@5|RUO>V+muDk z_Bhi^POWLs9~s5z|7@IR)P-Ic1o{~3KHJj+B;xbgo>WM1SHAJQ!#v-3y8cgVaMXA- zR$0m(UJMFlD)CgXFS%zh!uY4n^t51Omv|#4l60{*ktW@$z-mq^CT+#{`HFC|HdBs2{cq@&v~Ry>zL}{ ztqV^{v?+Od@{bg)*PHI5b;*y@Y{$ySLk_ao3eRNp>hubatBY)a$j`yS8u^i|9=T?Q z4oJ{zu9;H1fKXJ7^F$mPnrQ&%l?fK~W7d452hk<$u8p4NAwE;D{zZ+VZ)<%DG*)2v zMhw*?7PZMUDyCxFO0+~ik)Bu0&Di^0o4EO*O`b}k9E-MlmcvvraEGTW)Ho}4c%~V2 zRj1k0yFHho7euI7Gq!7lD~0WUB4;>H+UrS!Z%!C^#kHJa?6)ef^r#qbNjZk#er`WL+?>)+Cwk65ihxJbJj#8@F z(G+iY<(vdfN%g)29S3ORul%<(?|sT3Qn3qWRXwtl?j(zvAC!vA$_Yr?h6a-FBojXN`94iSYlVhMP$L5)@N4*XG-j95mRRSh%;^7+-r$mN^$ND)k@yCxp%CRaDL>S z(l-rCpOfrb3vZi-S0qRr%y@Am>zLs!ZaDbEJ4q1)UkX=)Ya{vJ8QvfD@O)f?!(P*s zp?ps}@8C#imwTz+90l5CT*vc_JG>w1I%vLZP@%_QE$Lz1gq)?hvH?gwYkJDoYY2L> z0ccQl0776is2kX^PTsVaG|#ognaxoES0O{tYfWHB00_>*5cF9CP!FRkG8qu?Dmk(x zNF{z0fKdL$f?69?&4*1kilrV4n}`7c=C9r9U7h9uA1w-AXi?^kcB3-gFm0J3a zWWK-i_wMo*L^eD~;RBhV;I!m_<0(D7Rs@yv+aB?LkF!Lm$90J-SXE_SJMMej8>=)e z+yod!*I*Y=^XbP<-s1^xo7kY2r@n4p4I!psh_t*KdM#K`^YYY7FVB_Fc}GBqzw3GL zkUMu#SSIaZNCy$VAMVxQiCdy-H^~D8q>V7Cf8zewTKEyxxSuyQ{baD%QMdRUQ&EhL zdbFR{3Vi`~x1&)I++Tjp+k~{F`2)N|VW8&`Z+KtTLDELr`xHLB^S4BRTX@k7w1_-D9hkCPh^Uv|IL%sRPs>B9Hvru{lU7AKsr`vE9&2n9WirdaH5ZbTsom6n07@&0KX0e}#F~M2y<} z8Q!CDe8WPoP2uCe_qvp5nHnQFf&GiUKjbxRjMudz-W3liu{ZguO|6=hd3eZU0(~8UzmWX#bBLE@=eA$ zI(&3<-xWnyki|~^W=`ePGJG#YCtQ-gPzvn|r&+4Sm(_6iSfMu&psQopofcna!lUsl4$W5qfYps{?K#n(O#F{B4PzI&tj7x=I=bu(}4_3bo(PBd=gb4No( z)cDCjOWwP^?__LTnCCVU>3CAuYh8U=QN@45x#JHbJ20C}-l&vh+WKmW|LGfv%EaqSfm^;&$DaS)8&&)_ZzL+$dn2BIpKqDob@5Z!Od=pf zSA5uvrvsWJX-ONhOt_1eQW4;RZ z*kky4+X`n(zV30~G+pGH5>hgGt{e!+)$*c$eOxbPz%`kt>V zK0h|vH&q^!gDo2>Eiu`{1>Eb!=k=x6>jhc60$&f^wVAA-z~@k=uq6e)p2`>=H^%os z3_@djPxL(k{%pxaUspO-+Azu23w|{GnJK=fqu7=&eY;ulmp%_$`vvaiO!u`%*|F)q zcMY0U1^TRQB$6nTSkx^9lOj-1MIXKi5iuqLE#(@y2??t04*}hR^AXgz{yqe1j6IrY zv}`j|ppvXqheRjO_F1C8B~OePbvnCawl9!bxnA2<)G~2b_pK}Dvr~6Cnrh6P+%DI-*fr{JCBg(z=RGao_$)D7q@;FXJ%8{U-_tZ*O6K@N=OsQh*Y|#{d%ZzDHv;p4 z{2Rjv3BU9$R?&5;+WUl(BurIXM@>sw6@{z?I6}8;0x2&-2?6!$l^?}?3L{sL%t-yJxEo@JK!M(B~Ui}fk-Ww3Q6*rfKe#w&dHu=khyK4GrqzV57~)R)Q< zmipdfi7R}E!eFoOH92#Wmfz4D(Be~W`7#%aMD-BuT=XQ zMuMM+KkwVn;&?-n-DwUQUQe7FNzygBFt+Ni&OgWgKJPmM4r=!W-^x3`Cqo-luXToD zDFI33L0Ht8#9DcFMG%hgr*Qac_S;3D1sW2epKWo;_q$jCUDZ ze<{=q*I$OxCB({sFzpl$$k!Q{c-tCZybfo@b-IcT9V?(GoKF^GzBps@)*vg2lYewqNYvIK|x^ZQyn7AM0CQfnMB$oldc&vGvoZ0=o%6( zBh@*)dz^o!4j$3x6Z~zjqbkx0@b9QfT`D3^Mh~MRP$W)o=zl|x6ntq-{QKC*RDS~I zLVlWmPs6imVZ&c7U~Fm%$}8#qPjtILs}4silxQ20fL0~$8=Vd>ht?3=@@`hu6bSi* z@CM(T?*CqoVD)hsemV?n6J2J~#mc-b{kxP>9^c9zrDsnV{h5dc^gGy7+5U#~vol+m z?eDHzkj4s!xzd?4+uuI)V`R49!M`;6_voXGB|$&K4p{vb(LxBs0kSJmHS$O^HqGeo zhMY#d?Ebw-C~!-T|6b)MUXbH|j&_05xqj>d9P!xAbh_$wY}zufQ$Z^HW!_YF(CKfE zz_V*ke+y*@Z{hOuCTX9D;UoPQY@{&W3crg*kd7PO>>sUPjhoMI_TS1E-|l}rg=P2l zcVUg5@TahLXJZptVQ+s+Hs~>bFLt7jzY9mfdkWwCm|s;`zeoL}`RFJ8CzW~v$B3u= z*9jbppYmtcl`a^hiw0b=hx?QfO(WeSZy0{2M+ z8L7%5U@v{lpG~iIPo!*sJ=Mn_2(QVO^zk&YKaYg-=EYye2oXgZAwK=xyH#$jh6Tv z0TcYs^*&N9LhJkB`+j@$X1TEQdD6f9E{)gJ?1t@)0nMZ<+_qsiBvTDp!~bpW_lv6q zZxBY{u&PT3`R`3+7smVB2hF2B3bA~ioZz>!TR--HPzU<^#}e9+#TC}6a2IRzNj=<> zPyDa2y>-zt+3n-}FEdNsr-{lP*@g*qn#^RbiT)gVhmP#qadnFB;*U=BpNmD3mLAjm zug8Y$wK{d3WU}ghV%0bPM=6zeySe_KbRFgCSG3v;P;DzvR_i)IQ6&wKauMnT7{K2{ zD^rhHABA+-iVCYF>-8-@j?eeM-K5|!)`l6>(}pmHL%3ha)CK-_;VuTl7Wgk>{SW%i zpJBTCJrsY#I7~x`$r#W)3+!8j41B?{TT+R2h?jlm-yF#{FZY-6%`5#cDD1)y*n|sL z_*bw-OZ{c+-evgn(Gt2V!=FY#WQ|r5_ELXKh0XoJ|1|rk)IW>2UG0CkA;?YP7XKZ( zk7|%a#h=9g+~S`T$GY$H-^KRr^}og@?8P11=kHUi?O=sR{qC?c$$ReiZ&03)>K}0a zYN60=Np_#)0^;`N{Fif`_PF}nS%`@a-_K}|tFxay@tfZib6nFsEoI7KzyAptvPsVk zUt|9V&s|5lp(J(AX7OCjr;45{)pqiGNf}4qD`E0`NqtP;D`8@7!$2vQw}hpMeLkpT zlfjmW1k<#{f+$1_Byu7(;EvsL(4QQmrEeTsLGRR@y?M}|K4@nJiA41~WIE}(>yN}F z0@fdjGeo-Tvlc>AD8@p(i+DL{U5gL(ynI2HaLC^*CZBQ#G*-`u7YiSxo$KiB>Q0Vu zW7vOWcH{`l-lAD_-Q<@%Z$^YA_5&h}Mcxp6^KwA#`uhhnu8-h{O zVG2MH)nkA7hwAGsCuDP5dDQM_e_T+9n7Y0`LAOIZz);KFw03MA!9 z+ZB~6ssSXHykOLGB-h1CAkke?r>LuW4_82qkS`zRu<&3VmxBM+VF4T%nU!a;j6k6C zb z#GG!?Iq)J`mZ5EK#=hths7?!+P?IzZ>X9Rq1gsTX&^holkM9~V*Q!Spb@pz-!qxF3 z;rDh6G>d`fNdE@|?P1NH{b1nkDBaX#w(^269g#M8*7>N=?r%W0fg7k;EYAj7)bff5 zO&O{=>4p+Qz)6=JCHg)en5ihsS;7l=*cN`z3xPNFEv`!mu24cAk!!r1?|UhrDlLL3 zC*xEt-M2syxxp8*n_meOD+~FaR|4_6Xv#SUm*}ai`n7<)_E*+`Kyx^m+&UnTi2#yb z0|HBQ`oi<8*}Nfn%~@bzpm8v9jR@nEiEH>H0|R|@IKJeEe*_jp#C-fAbi9)lwTcgX zFAyJvgu;VA2$cS}>-_KSH(2M3hX%IlAhW?;qZw;IGSHo!8WHe8)*}E1z!Xg?kY@`6 z?REcyX&xdpH}Xb1B%KiJPKu0A0(VmKvA*L2ffUiDWEKDu2VbYe>_`Yvzp`(~qf0B< zPvZma(EE`S0y`shFsoEe38dtX7z^S;=0+swg5AGe1C73f0t`DPXeS=wq=}+Hwr>1b z_TkJxHhaD(us!UYrT^#_weBa;b#>qTtR z{@{4*!)jD0FO6WH)Ubp!5)hV&Mjc8u!cx#k3@!JJSnp@J>$|{HntdpY220&SnATfv z9yc0O&7e}JXPBM`Znb z{0s{ce)VrH4=jv`E2+VcEATC^S~z;Am3Q!yZe_u?Vz*f)CvFQmu=kZGd9RR`{?B0tkCma{M5 zOpzxY%N|OIym2uYcRG%d2(~TR?f4A`vVW( zr)7>2l$$tr8IY{)1P1H`@o1ogl5HSUZ{4_N@iNP)h|)_T5`;9)p!IxzV3UER9}cu( zrH2AwO7!gaLjfNfb|^sk$a^0C|7iOTI4O#4@0nQ^SQglxnI*>sl?Gz9f2lML9r>R29#qECXDC28e0)$DN6o%L zezu?g=_@pQ)S$;asuV3;-s!2DR za!6@{zK(y1>Mb<=D`h-&X5Ae5fkuC!6jSk6=w~q-u##T-23K>?PiXy*{;awlMqzKN zP)tj{K+|Fj89MSK4L_*FSWTZ$#ZP|Ww!_N1EGm3NIg0n0gA|(8#Br9fKPmfapt}Dt zWisaRz#jm3E7BiI7y9UTr5oMzJLXqOPyVi41#elqKa?xcIMu3xfeUH;aiuYv`ElhB z|8gbwh_#ZI`Wj6IGb$g1?s*&$D+NY@b!9CuOih5fOgb6DO)h$74U8>flg{A5? zI#PsO{A|^siXwG_x4wru0AF#j)Ct6)Oapr0zX{#(Ur7n8>!}*_U>{YZQN<`$vUclD z{I{1iS;?AgDORtbjix$=4U$cYrOI?xPgP?`>Z!(Pd{?y$PjzE2wNY?9ebiMwA3qA38LHF6pC=3mu#3!_8@UEM31lT|ShC%hPb75Ape` z^Uqet!*BT7*=o2({TElmQ4ru>%mF0nYt$HFAay8-nt>` z(NM1clZ2FT_0|qmTh=0dlp3cGM&iHwMyX?m>}J2~YJ}~LZ)*fgzh|W;nbOQZP~tMB zg{;&fQ(DJLR;KjhDW#|BLR)QrX8N76hLA7kWy+MgRZYQ-`ye-+{5t^n0{2@eThOP6}+W@0tfnPl{;x73mqIrD?l_ znpYDH;`qZ&n^M_m^+CF9jM|fwOVy@SZ;U#U`d^Cwj*P~CPh6_@^j3{g`K&re4!#2a z5#CGxl=sy*_1@}a>CKs--iRZ7#9gV5#23jXT&eyP3_j^ya<%$Njohg}p6MHpbMaH3 zDe8H-Q;(-BKKsM3SolY}V%zV2#m~Q`D;ECdR~)&Sy%Qd0>GL;J1?!{Ym&`3c`z_}F zl&(1XqhE3KSf&NetFT*E|DLXxn;vEN)O4qdr=~isv$7&xag_E>QP0m^I4xbqw^Z1u zbv9>azBtvO&d-@yET__&aKqG}(?hKO$scpmE$JTS`aR_Cy(wKW^(Oy8)=o)R97526 zP4mdF={{clmG#lf8#`6Kwr0!SFJl|POTz@`UgUl0>dVQOU!f_FsZnY?L!DXe%mY0& zLoICRe}ltkhD@Q_;^~V|X>o|X&NTI+my^-Bb%A;e zCr931sCLK-{roHa@}PQgi`COkjK3K9lWwb=Miq~#`J_Flwx!<}sRP-6-Dt~0>L73W zB6U~xDU)Zv$2{rg)Z~j!X)*mT9uE<#C2Hi9X7~QHW=sBAvlEJ73Kgkor3THe#eR9k zPF}WJsy0f0aN`uckoG;Msx3FMH^8J9sM;G~UcGZ;itfFYOVxF!Vq?=^%&viV-;?T^ z?0Rqh*2Dk23J$})N+X_8yS3QK-d)PR3Z9ZpM_8#!Qr+q;eMY@CyWK(dM$BmXMV!9F zf<pcQQvo;(uuf-vE#=*tF~&h@EhhbDgF6d0CsYB;n&FA{2icdF7~U%Z$T?YyO%)iog~=cC?H zzYNi9AF4W4Y*#tzv$Ry7~jPdsgL?_0;Nf z6$fy)sU4{AyK3*y>AM}7**y3@W^-g0+O6G%t|~r6<8Hgu?(DYSlzb2EQdco_IyY;3CWl^n zvj^)<+jgsc=+510FV;bCe;Rvtsjb)~)3@Ql`oNmN)K%7FKATc^c0HRtspOA>zO&iX zdsJbhvws24>GyLAM(TK5_o!C~@$2R}AFI9a(~1;eZ}>+E;VyvC%sVLj3C3i&fUcgp zw9p5eeegWB_*`vANA{_$&{Oa;ASBiJ7|ZuU6d3pTI6|MPs?>N@RVOZ|Cg9hn$L;C& z*b5)+IMHn8N%_=d(_KC9VIp|V`6BPN1M19RqqU5au%9h56&YN_C$AmerC+G~g7{VI z*v zt$=Jps2=@R(7s>Q_W7UqZ{6I3_myV0#b;iN-_+yz!7fzNNNYh0IgO*{oYn+7fy!xo zqxBC%?U~x50Ahptp2canOHacXw2adZz$@GrR>wR-RS6()3g_} z>McLqqcz@xd+*^M5D&DkgJ#uf8DMG*+woCUS}y;gXQnf6TSu*ey>@>{SFK&06NAy5Zd!ir$|I@4*V98?HKESJ zqp5Lb9z8R4wa%-4dAVP1kmDD3XD(0uA=Uh7x|}n8Now$;kJ0RIT7%lh{Nh5oyqngr z_MxX!7kAJslzQ%6ohntVX7kK#!4@)gCN8voXHPA}ih&NHwW&P28e}gzfhje)4IXaC z{?xs%?oSPqv-v=(cqm=0!a(Zk8LNLxUEP*K$jJj$-rlQfpnJ*YwXMw;;GI&X<)t`} z$30RzH@9hO71*)F0A7iAuAu#l4@Q@ZT0?JysFmf?dP@U$Dbi}vMa5cOuU3&34A!`F z=f(h)b=R7+${dor5^(1UTPEY+b+i&88eMiH!p-FIHh8VH>Zcj z)d;=bfadkqUI_oxBDX$Tl&=36onkSqK6`5M9adzT zoT=c9pHD5We+-S8zr!Et7%MidD$ZMSN^#|> z#Wz^7S-Np~u=Mkj%ivy1ak*<%Ur(@N$ExBER+OrWGag5=OI2|#D|V|Y9ys;t+-11R zS6zLT70ZRH@(-t8eq=c=pP0vg?yFkkYKvHHS|^iQIW|T$0;x8SYKvM8^VQH(Z4s;C zGWEnK9+=^>{3K*nTZn3lS`F1c`BWjV8o5-XfLGx^KWUSHi}z~c2cv)FZ`<^qcwv}>3oiMf7b&QP#c+B-KV^7S@8t>_<$AJhb8>0N4%fT(XPrW zpV~e*2aFDac1l(5*LIn@@2hgZROP;^%6(UryRGWp6LsHIT|Hct`>`tbho2*DkXEnv z(W>g{RUI9ws{5fTccSxYRqbxA%FU+nWm=26H&s;}YeyHBY0ahEt7_&{<&IZ%dUI9X zEmgUnsC1wftvj=-;*R#TaG=(_?8FRaRb9KYDpygJ`=YA*6KMUts_y5i+}G4%kk+Er ziEa;8T{>~&ZZR9U9gq1uDAmJRP}lUbnEtuwj3?P>QQjh8;Hn!{&Rxi6}62dZ+P zROJp*!C)=g;H#>N&#Q7@dKVAYp1FYZC!zjzep0KOb(I_UN}tq@U+opQ*YD4w&7Jgo z??@+oLNMowiI+{9Y)`&o5^d_Dx21>hU#+q3q)GP0Es@HsIz3!7 z@YQ=r6zl{rYr#ZadBfIYV z>AO17-fnv1?7=9PuwHs(EqtG&m)7Y$vp>t!b)YkNy=8Xi54b?7Ka%*Y-ZcAalr8#@ z*N0~ZwsV0-RJulwdIJP~VRkq&lnac&@GV1uKySbZ{jTbbgiQ6k^BR)p%NCpF7Oxm~K+{hHn>7@^lSeOB;V8m8->y&e~9<08Blfx&~g zKmxEAQUfG>_$N?N&%drCZy?o9x5p{jKzIn38fZW2dY)7sggmPJ>ompC8)c`O(*1@m zM>7`yx1v=JAZ<1Di>Y^^ZV(^SIjShc>a8zCZYBF~OQAlB2CxgMt6K)?wR1S!##XL_ zXUFv18Z@C;zqbmXHv*q6aWO(oO7xG@ga2NlYr&i7i|Yzo0SqbC2X)9iz<9K6h?FUx zk9=dKII!W*yk2)u%kv%duJyj`%>~%?i?aiPX0&yn-m1ZsD7HPH3zPxghDU0|%HG)S z`mI^PepGOt9;N0t6xJrLm%cLi9&PBQw++8{9vA43c0JLa;r>1Pp_kq*_?~xqZ~dLD zU|*WESa0h!?x)LH!7J#TbM+qHtLN%JglP7;x-@S!cEXl2{YcP95XW${evr<2M+WIL zL%GM(e?yOPH2!;|5j}LC-mpoAJ|tkL4u%|`OipqqGc0XAPw!uzxvb-|h0B?;l5U7s43I_e3YT-N2)3YqM{jVK&#HzXH_jKp}I4w z+j?a~^`EjsM+SR+FVepYwf??lIFO4Ae*iLSs#Pl-s0CObuqGhABj}Ph%hs1>HIZtE zQ{)~4WaLwvhCRG87n`D-&-JhCfb8BPK!&S6fLQQAkMZNjjCOmCb}w@#jm-A@*bm6A zy^p@wJ-Yze_@AWv-k+{N1jx49(KI~Uz1U7%p_n~4`A=)=QZ>-)pXfLW;4XvHOZ+ZH`A3Y$gsS(elY2ST)Ov{p)8N9#?` z`VhAM^{dxWzbqWazA2dH(qG@RV#`A{? z5RhqtilZ2atxI2&*?@xq*#IK}8UDutMgYqJ*#xvYe!DwSW_W%Wkae7-RaZge{vAFt z%X}reNi8G&a+ThH*gw5(eVSToxAY%-H_EJ=1?Y}FMFZ5cr^rOWqGgKPBOf4g}9ly+;hO3`L@T0KFkAfDzJzB$@4T&HO~ z6u5`>Tmwn-Pai9@b%y{ejIj<+Z`DKSm+iTq0ok6LhnLYWE9N10vE44m0)na%uK8X-)1svDq=*Xa%agoNsAnpx|A z$5@tOOvbnB7WfaJnQMm8RG(wDxpfRo!lc+v`5O)t7z&k1|LGskH$&=t8-HE~ARDGP zAltZ4L6S0DjY64i%<+J1<7T!(X8zZv>u&*sZq_ldAbrD95I3WS$5Cc1B&V*w>KUZh zr`vAOAN$je&fv2;o)5P5=l3JoH|mW>{~Mb56Uk&AGxIo^>1WWMA&JavGqXGkVw7#o z3AFD;aae2M=jIQl_3wrrhWTiCT*FkUs%2$?HLkFkl30sRg38rOs8P_1k)v$ z9>H`7rav&3DU3BUs$u(w?H#sn z7_~4C%(ySp{g|kDjjoxeckA%oNu#o^GB{vTo=JEn-I-*+kG9U!`=7N<{r59qqqAAC z8L-ir0AqBuIsg-3%r}L)Nxc!BNceua<+&o+({*d^+Ri z>vGR~|KdqAQ_f5^#p z)C>QYJEmYeIN#s#<$8==G@?WEbosw1ss2BRUdAZ<{TCS}9e-MH5FU0`I4}aqLAnI# zGAeySPmE}Ab~w-;Nk{5~G#Dw4G#2R!q}!10MS2YBNhA+x1JX{U14v&Z1>D0k1LG#m$kvL&AY`k%k}*LmDxJe%+?WN7f%24iq2>NTo>UAPq-K zB8@}3326>eCDIb4l}OJby@#|HX+P30NZG@{uaR0K6(bEqx@cIKp6j3+Uh8M{=E2ah z;Z(FnKci;n3z@}6<2LFoY5E#{G2Z9g#nWeGT{a?2vpVYvUWf9nr=Oqo70Ru;=mw%R zx2)9#>{)#lC#&7ADg!_yQ2hK(sgmgaAaGLWL2xII7=($L5$P?Y zeMm=;jw98&9QrO&6C@F-7^x@HP$UOwEK)hr14yfoUZAqK_49*QdrRNei))6hE3xoM zeUQ#Z8bH5n!wiO814>1@8fiMxT%?DPRvcHP>&?!~65iP$D4E?{xE@{z+dcXgULhcDW^_y!3FY%t)s~^t(KWNT- z_Ul^N|5ycuuE)G`8GDks+y~46gGU;MG@RT6daEWKZwm*yBI!uok@_JGL2|tN59rUW zFPG=|?57_f2b&ar!@%$bV6uSM0kTLVtJ{oxE5NS+XQk_|T?m^G`3C{NPuJabzu#^Z z;90P9*}cC$=zD1!Rzh=5x0{Ci8E~2hmLt<6U3nOJ7EjJu1eZA;h~361^7Uby;|~Om0}e?y9K6AAI2mwax^6%6OjED(GI(CPt}pToTMpn`=?;Zg z{ecGpKAdj%1M;nrZ?G|(3TvWipcHu)>nR_K%ooU{D*xpV;sU+}-wLY}xA+au0<_Xg zGVMLT!$$$nOW%78`2yryY=f%=H?n&Vybt3Hu+ax6*8NuGnaBQN!1se#f7bBo9sYXW z1Gov!MOHWBb8vaUser=(S=}Dw84(@>90U&&tLy)bKbi4>=ce1efIPEv4g&T{*L6MY zkI@g%De&)ok}HqkWx*g2E)rnTV%A~9XoOK_zyutfe&Rb}x50KTBw(x7i%}LlRuej0WUxWtJ~JuALJ2sj9J z<*eaG6j}p*4%jJuGuJJWA{G-cvm<68&oHwJ@E$;RZ!g}jy9_Wh$n(f|#-re}gIofLot>KC0pum*n-)d__0nUsGyQhGO|1XC%)mvF6yvB<90^pWZ+;wk1^JHw zC2(8z#E~=ocEx}=?~|$<(AP)*)quy+_fGB?Nj=;Gz>m^cz2=-qiq9+nyc6wG96aE? zzQUlIrGIN^r>*!Fm`KV>PnWB#c5l&Y);H_j7^#2e`l^XK;Z@9k@VbA{V$1`LCvNft{1Nz!PJ*z`pCbz&KpHb{rSzd>0qU zox%mKoX!QBq3+kQI0khq7kKj;E>Mj7KCVC+@XR(`V8T2u@HYDY8R;?P+`0(2zKLOuqV=W7e}}qvT62L~ zcX9z8Ezh}v3#>tU1gQdTK0@2eI&*=Wksl2>4R9yw-o^CS;fU39fE$rMz-Wc1ae*iC zh{xt|fx{E#b<^u2I;@h~e0_j@dq2?_d)Lt&& zVlo#Z4MyUwLZ^84cQIgXv|HAS3zTD$ErHj?6$t!RsL$)f1?pe|jnV!|w3&}d zP6XaAL!WV^Z&BVfwj77PJEBvhEIe&%Jk2Bw@)H)P1_p?uyrKY$hHE-*z5)w%5cNGD z#gn66xDp*=kRF)8I!r$2MlR4|1{Zh~b-S^6-7v@x!2d6}{uw5<2KSFeKM!D{weIEu z$IJ1Qq1(7XFFer~X#52levkAt8eWIa58>tsfMYPJmoe}~K;`|ITp0IFKnIl<;7M-* zhS26gOeh!F?0_f!{tg_7!+@8f{d1__g30`G0~ctBWqDx9Henm@Z^~N=k2+`8@TT!q}52jW3XPB{K$4(pexAq2TXJb z+6Qmq0>c+_fvZ7JM*#cY!=-juFcb)d0>Mx)7^L#7!c`rT^RV`4AOKnqa)I^8<9b$& znk>!|2n@l%`Xnx}gof29Y}a7<^<3ai(A5%*^&|3UV6IWRr$*s|E>C0V_kf>Q@QklM z#sxMYIY^&A$^|aKvYuV9}C(I?WAxL7XRW!JQXp_H&|VviA@g?x*sH;gUIbdFs`gP?t-@9XFJVK}@t-?Yecy;oGoQD9 zLvv~sb}P6I3z@o`@nHNN!*-~j>dh~|OZ#dS7Kc|4_nU!7rv46*P#e{+0NYHX%=|q} zQ)*-E86e4g8?UBF*T0M@HoQF32qKm?pjkK<>*UYeXW0LuZ&4l0r*IB{MFIm7mE{z6 z3x8Ivi*IQTstbO@?qfL2jC3281!PzCw}|%T6cz`cpn^IWkT9>)?b@|6t%pztr?6YOl&;3zsU>4;`Zm`6`Kee_AYuw=d^^T3M>+!XZH?=% zf`WE}RByl{?gEFn6pwKq+Oqn5Kz1z~duk}q{uGvCG{(r>b2aYie<>Gu1{`JAIIyft zhr7Yk-owQ=L4Rxl?1pXVygND^iUIPFmI4cpViL{3VOF4HHp%_deIjgziLC`|nutL! z0zqc__zwM?jS0OC?!&0?Jka`yKkvod!Zx8Mw_@N;7%UGgXE$~|OQSI0DEg&dVY7NI z-^RU}Qj zZGn9H{j5UC7>GT|C}3buzzrwH@{!u zjI0(RJb&gdgD!?XhQ?dH(*A{c!SbI$7un#k>~H-{NN+4-IpAGLzhG$>L%<9~T?4df zfVz$oA%wAVJF&zU1G2v-?%)D-!OG6Z_0NFV>3gK%nAuUlACP`T8se1=F1)#5*wH7sz*eN@=;vSH zy2p@C{=4#KE-(nG8`6N&AzVO3eLzj@Zw- zAA(d|l<6}B%E(6GyA~)kColo+&j%TV(B}={@)slBiMk(_gB@ZX9adm>-wTnBHt*uv zEhrxZ+>Glc@S)9z_=dchgES1O7t(&T?S^{};`+{o*zL!$GnQb7Ou@yQ0H2x*5sXgy zptCEGMj+*3utxy5AQe2p1-=IS9E0@7ay^O;HPo#`-Av?jk@s-zW+0(62Jz76UW~C5 z`4IZaLA$yrv!lm<9B*~}_%URjM`H(1c@KcQ0Dsm$TJ%$Q{IR?PFHrXs(6!KJgLDBp)A?PAA+bEsqcSi9gP8rVM8A8*`!sD13J;0kKm0iXfh)dANU(6bEW z(I-Br(-EbHB>Lb21}wVC2ak8eeWR#NCsZz{z6?A_6B(FF_W^_kUP@neik%T0MqhTq zfIF$MGcK;BI0GTNoq^}+DIe@);8O~90pO`)m)POpE!4CtN@_S^M-e5F z1~M>$uJyq~47^2e0EB+Jg5DI-*->gLq4qTD&cKg!DL^PZnVyqyaUwm-YP-`X47^2k zWPphzGVmE)AOn>h>2X$COYbtUnto-VIkiy$7ExaYUZaTs^otzhXsHrw9Be@^v-*eV zOIClIiuwW-^)FMQii!_e#pSHxIl3Jc!432j1Fz9e6(g$DQA24B4P>A@T?k?~;PqV#&>d@kA=uIuwl?wD&YYf|6#~m%{QXSpYp=WhaO_nDbv07QdCRAwR z;8Slz6qGd^rsW1KzK4b-o9jctz^iQgA>y~>_6Hn_@L z)HBvMNJ8&ezhE|f)hpIBRP$C^xu?XSybntHdo}ySHcDYfO~wUY&|M*!h)b@02MO23 z?&EYfDI~Ont0Y}Tc9SAayFRvzb45cklC~z>3C-5DB$eI}dn2sKiFncxbtNH6l9W{M zq6t%DW1@zECUH5Dltd$;+wr@D#rULqtN~59F;<&C6pO;N>Bd;AGfvOUyRgt1jbnb3 z6PFYgUgE~lzwCU6tapjtW;-G*MX;>`(Rj7Yj6gw3VBW`y|N` zR7Y?GIiV_s;5_6%Ph5-JhG;7ZRn+2&9`|m(DP{+`q@o&lc2SiKUf1PishM-GCM1%m zRTM+h)TB-0r^XIO5?a!gF|4fXhKlq=5a0BTT^dm}RZnWJs>)J4&TGn(e!bU!S}Z@v zX@-(Ws)~T$G9_GFwDJ9-SV53e48wJlq@IxDz^*OR;_0!c!wDIqsbW%7l8&nL$+iCE zu{4GjPsZ_FGOs8$MQ)Fo5ks@>cw9?5Ntag~#eObG1&d;5a6&v0kK=XzS`yEnND4IX z_Sk?Z>I7YofjixayNdWC5I3ixC3qcY#AXKbM3onkSSHDF5{fI+#+kAHQ6rh;ldj>Y zj%*9M=Ddb&vX#uPYz1?Fy3m9g$YtLd8yHa>Sxm@=t0-~V#zViE#wgJ4;962Q9EaE9?&cuPc|10T z2F!{*9&rRiH~1v)XttBk75nYE#(W zCw5veVu*TD6cimm(riWAmcENuctZg894)RpSfls-db<7Ym>v}bCmweV3FN5?SpMz7 z;Z(Y!sDK8%P?X~xzdNP{BdVZabsSNWWl4}^eOJ0;Lo`4VLR`k3TJ3$Vnrv z$f{!tO2Xdb*L#o8i?t7O26mC{vSrW`Hm}I^3B|fcHSDUmoe+55*0EUgN8*cgpm}%CPZqrDAqnK*$KySMIOz0)i$)-sr8~*JI=LrS5+h) z6IQWE37WMi_5;|7BgsNSP;E)nl46qPJ{0>Z3>*p~_7mt1+sqa2qTnOoJ>VyfBIq^{ zEMki&RJb^{hSRa`xKnVFaSR|D^B##U;6w?O?_!A!o3~{nLCYSAZ4ZN!$-ut`9wjjP znNO8VVq?NdMT~2*#%q!*OW-c|rK;)L$6`-#NsOi@1v{xE)dZ$R`jXgtVVRGs@r0-v zyo$#a;}7{ADYC(9Ni0PouE$+1{xGY)j1wfoj@xk_xD{O0U7V`TlM|xuIEI~c)r6k3 zy;+aP+6E({ph_yQYL1~MfM01zh=SdUy8ZRe^6D>-?F({o#nBV0<4E9IvXn5q<11p9 z1jASc*f#A5Rsy#y!o{0VAjb9lXhlO?$s_KGuskSWIcu~vOPsJ|COY%xW*0h9S z2yr*Ad*?kJ8yw{9L|m|CNsNQIojBOuv#Vpf!-Am+;OgKef^LAjzv*KwvL-e#tO>d! zDXQeCt^uZOzm>Yi#S@BcU{s#h5)$u<-jOx2Nm*gg4z?7?PE7#&j<(&O=$PkX-vq;q zVX1s;jUAejC?R$2AmPNUGvqfAq2!V?T!l!8PL8sDi68q7XjyM+c2* zqHM$k$xe!fko4YvDRx1K!v@lA5T&izp!)b>+VFDh@;p~kj6_^@@zA_%==9Rdu|GHi zyV?=s3X>rc&wodyt7C%q$1AaGv!j||J4s1b9X+YKa#Ea;bv+f_9ZS%Fu4WGX^m^>d z2+yV*2l2%nUALw99a*&ZWwSGVd@R=4+x|xE+hD|naKh#Q*~)@!Nc`L^nvy7X^F)cq z^dwCdT*1b|ocmU6OIDsCptT%#Y{&*#O;DGuvGX`NnZO=au`?Ylp}8*Iy)`C7#j0#t z+#}@1i63pXq|Wcgc+OB%#RhYc;@FsR*`dqcjs4D{d&x<-U_zi<^hMXa7rUQ>6j$T6 z5;sJ!Hmp0Hu`L#lBr&w+N=}lO+$1Lcd=}ZWu>BnDQ_Xhq46dW`FQjVcM{HGyCxy6> zlpy+&Lh{8dn)7gML0&wWkR?fg7)siX_7auti?z?w6b(Zfj*ET6OAc-QAof#4O=^zr z@{C8y*iOR6EGofjh4Gx&!U7{LS-0^WZB{*jHt&cni>hjzcSK&0goF)BaW`jOLS=6; zX82+3drlF7Q;CTV&<3`w_wY`L;i!n+=_O{C1g+@_PgN8dt+w?IZVOTv3#yACuCXHyy^R5-`C(EIdw^t5}IR!!V(6}*dM!x zgLu`GNo+yz39uL5;}67kLlsIo=vwFTKtPBt+*`vS`(LqUUg4LqA8T_iFEB+&S9k@C z-j%$P?_<3~VUQf=3Be;cuHf448}!c6nCQLnLo9~zd7f8XM-VkJAvkKnYw&90ba}sBZ;C^}%5(T>!N`_ZZ!@RggSg=)) zK^$9D#5C^8F7>s*Cu*B_aNvIl;1f~+%9^9Zsb7wHEe9zB87L-YJU{~6$9q4=>=O*j zh9NPMR};LW;--ZpG%<(J&AFx?b!1hycUqVnb*yXt z%&CU0i-O_E30}1MxZsKP%-+GMBk)jD!5)&Je9dr|WKU$0v@speFOJX>%S@{+-_$oh zjLNthy~rYj2t;yxS#~da=Nhvejaq8v5yzQdbJ%5y1Z_mXhhDKnl2Q@b@{l7n^;e4mc{z5Fi26tBZ+8YEGtth*jpj z(A8`agaD8rdlJwrRM{4j{PLQuPnZ-FCnT6Pf#ty6s*OE^B{o*nq=Fz=vdNoga(n_d zker0Ntnd=Ju{WDH%d$8yHe0b>2x(U_)VN09O6E=uyUnpREGbNoL=srvC7TZhqjA@T zHsB@=Fg_?V_(;$=yid(+8)nnS>SQuC@)3G~&7rh?K$*cs6O zW!`o^uSq2rnWJEVU@b-4P2kB@#Sy)4ip-`#>;yOAXbMo5fCg-cUgHvTR*h&JT807j z&=nI2FkAPgT7&)lTCvlr?QK8PT*r(T9ryAYkIfGH(Y(rD=BiL$GH$!^jHrM)fy`1{=CbotK%;YAcQn9x_}Sv7y!= zDto`Ukg@d~y0{G7prFj$4Mjy4<4}RXZ$w^###3*g`9ws7iVCHjR~<+pNW)FFXjG2r zMtK{8RB?F4NWu&=60g^q#@1;lwcZk|#}1;y}^Ruj1g!aST7}VoQQTw?TUhL7(%J-U&H2Y&qgVq!wp(I7#RWqePZa*!Sg zkeC50P{s^o3fkr@4*DDu4zPU%9{QExRodoV!8~w|B)AjUiw<$1d!-5UwQSC@6fi)poqbqs>2p94JdpxH8NxOiC4((5lPKvpCqar&Lq<81vk`YL(vZG3GbH2Gwe@ zUMp)~=7Kfnp^Bl?gdKmrb|3os zJo7XvikSJ-dZIZn58FhArVG`E7kE*oDHF|gQJ@<6BowOzM6=_*QhOjRx}c~NEqmB( z171M!%=0fEcZqC7b;1z4IH|1tXLQa-N z5fT%As-z-Gs^pz_i&-lehA|3_7D|f_kq-lF4qkU`c7f3gekbyA7fKXlheOMznQuf5 zFl8gXLs^r7_{7ntCtIHqU~S3_?xE&H*99UKDh% z@m=N$c($1BC1FEKwh9-aK=0pe7KhO$5r@A8y8%{^X8emjxZ5o95_8S7LmbH8h$o@W z@P@*Oh+dj!Zs3wU)DrlABq%9RPDPpx9}@=$n2tRa#|j8=^cddTWR}835eHQ#1qn(B zgd7|itrmb~!OnHDwhEuXrpEHAv|*tsN8spln1Q0hz>@?=+n?j}2;+Y9wh*VoJ&4uA zBHB;|;|9I^pgA#`OhDR$8A1}n)u{+abBd^aZc$shw$jYy60j1ONehD|2`e$~-BXE; zk%wnV8VpBx@;I#Q6^qP{5tVUJI1pUsm*RQp*Br)!pxq`lBOyX-ldzufy$pTGOoXB^ zE+9%7mf^mDYwzYdC#yhA6u^pi;4P7`r;}4py(+tK^cgU0W#)pEZ#m^EI0*QZt|#G& zQgv0IR_7|;GHQJ&mQ9`hWl8kpTCLoN9ygcN3QGwUds2de4_z3R-AcNAm6?pdqa!dCIH@MV#WZ_W9V)Xen>IXU zJ`V)gkkN3rCBZudWi@Sm+LSmRMqk{};Wz>xfrz3lPn&X>`G-=XC6Rz)%qP~Q8iV@* zA=p*0xMZwv!t<*kv-mgy9g_8|WE5m4o=N)dY!!Me9VYY$j z;Ua_eZ9pLwy^miq7eTK`f{5cH9sy78$_mZiV3z#3cJBtWM}GCT!^IJJ_5W&9=CB`h z_`gLJsxaU${&b#r*<2rrC@?W)I5yyVjZ07*Zp~%3$$ep{hk^t3I}wM$nRKV8s^>>E zI5y$$XId7Fl!SO&E;I7)gHKn(E`-crUWd4Nd+rTYe5rjEOJZ(xM+Wo6Y6-SJBe&uN zOR8$spjxZp!ibrq&2#FJ(n|2nq-8Fby6TShUH-xm2lH7t*MA%yrn>@LaA(m=0NF$8&UOIzGu$C_JTyk z2G`)8(%=bqyqDfL2?7o=2dHx(Q5DWJJNYUd-eF!IMpKA(sFK)S@P;TG>GBWFD%Iy<`rilIx4IY3v>=hx%?e>v|vUFt>vI;5(H>mHCjF@%tt%deiLc zeZA9s0M2XBKoW`&oG&tbm&$v&R5su2(V%)gmSmex51bnZwj_q}xC{TA<2|s)d^9_% z!>f%r0XREmjDWyrx#yF;+dRX&;Zw6?Fal>Y2$7edX2RhV|1$SNS~az}jkoJFb4xI) z#-$`&lnxjRTy(PWeeT&*c3Dw-+P~jy5YgZuf>8(u4wPC|IGWp&xj*vh$W28Nk`94w^G^ zI2-Z}E@PfoWd-()L>GK#-Wg6H3yMjf!m)w121?;Zfsl6` zeMeoo;32a+4Gmhq!`eqk1KS}kGxgI^KCT<1U{9+tRfMds;pXEN=)3T3@o>F3+Glk~ zF$U9>n0-pHPopW@uzE9ZPnLCmC<1q^f!?8G!Tknda~N0|QrwhA{T7SR-bbxQ-a9p| zAT#5zs)$42ks#O|+uK{qx;%@6orJvwQ(Qu{0+B|tbFB-)I(#BB76^g@0#meS&~eTh z6_GT^a=1@y1Qj%}+?n-g#p2BP^9&Q2|{y&GO6?LuMVOdq+#fBRdh9HPGF`K&O zStGq)>RGpi@}MB9EOw%R10&`~b2#grJZ76pV6nEUAp)X$b`U}ir zadADmNVm?8fQz|cSQ2yOI&ofnq+UuB3WL>%%ma&v513M1ew6YWTJ303zO^(g!7InZ z*^Q_f{MZR~dFr{suo=N;piaP`g_q7*k*ekpuW{ksfZ3@dY-1x}+t50Upaonza4;os zixZb*#jDrYN`}HPlaor^aa6e5_=F;C^!tY838N0~=wuRs5k>n~x>`d_1tJK05e`F9 zcr8^8w={GQL>djKPEZ5vP4%eqO|0SJW|kBR!^@CBXaE~nhc1^)ZfB2n2FS}bpi)BH zbf9kO>W+H1(yHR3Mzr@Vgr#S+w1!2%8B{pkunbT`e9OIjyX&z&wy)GxsxME4HDlU!-o*IT(&GFToO^qCwhynVNc3g_>x?fe0lf2{%aM zt9mDhJnG%v#(F9gRj`=Qt9Stq0yk9hSiL?zsXwsDsza^LusDxSx8RQv1cadBD8x=e zJQHL&s+}csP_SUGLoHO{-G*iBEpBHmz=FVC?I3W2AfyQQcbxinu!cuKp*q|)h+ymR zZRyILc=O$&SfTf02kXvY814{RMNAds24*BE^GN7q4T`|t*Ws{${{#vncr?|ol7e|* zct9llgFg#~kfOWy(tr-u1<((m!rBP~&RPd*c6@$)D%ffkHK^VkEbG4dDOSW`Yw!YM zMi@+o=FiirE>>4~1;8~m9??q~{t;fI!>ksI2Kfq(mNExGgQj!^gP%cG!Q?T}PBHZ9E_zcuFi10X18$_#f9;U1ybg4-yHeE7K$3&}B z7`6r|G9efWEMLRbR#Qn|OZG04tTr{mupn)AG6C^@ghMoEBkfbI6`T#%66OJC4vb4! z=yaiOog0SBJOM|#3qAoZq9rOa;;5&7(&9QUg2zrw}=>>V33qA_R4npKI zLZvjm&>9Y{QU||w3{jR0T`}JBafR1S@=1gdnVS>(s{D4k8XQ%`!3sx)Bo|!w9lu(F z5sPWSs|I!sI@yw{=CBtLe8alKI|P51N>fZQPz7d%4gA6Q)?vTJ-}U=YMMPS#Gzt_@ z*x2%WezgX4!E{!2I1v#a*0!aqF+Sq)EFK6M6?fkEt93zAz}0leHI!kxCVH=NL!0BZ5zmTVL8I-3g5M6 z@5Gz*tqZWhdZ3~q&SD&{pORJ)sEG*y8XbrQ zhL8|H;@5|vVc--KPKCHor=ZY$OB4E8av0tU#L1!jId}j~{w~#8LWBg|SA(exy9NG~ z?^AR4w)eI2n4_Luz!3oiYQVA8WA#b+!gO)Shq+*JGzQ325JCJsU5_&vq73&R!YXhH zE5aZ3DX+3f4?|Og=m36XFcKqiygt*!$9eakYqbgH!3hZiTSf#KuMU>t^mc!1O}>Fs z2|Qv~Fss1hlEQ6y4+m-A=dsT8>HzCv4q+P{>``EKz>bGS>cz^e%Y$JTQx%~t;iv>$ z%#J<>FW$DsM42NC!C7bqkkqzq-<2oQsO!xJG+>ZbFRbD&xDRoolE6-q?@rxB9}cpP zgNk?qUv|(v)TtE@E{>3fzvC{OF)MD!+9yrP9;OFWf8dh4KN|>6%87tpf1Uy z7ZyQ(!g&{LQs_4cLxyR+H1Asawso=F;0hgXL~t=U$=K;92a37ldS48)CL{P|>oW9D z=nyz$10L&*9bugVZ!iuiA?60%h*=_r{8}E(saZ5Un!rxC(G&2EBPF`DDX)l1$3Xoa zHPZSb3SxrO15N`6nj*Y$@8sd_6L**vb-n^N$c9nYjU4D2rzlh$0}&9DPD);X8}br< zVF@QRbc6um7{j*xAa7X8pY3%>ST%4E0wEbJwK( zn9SCru>xA#)~e@yl(c>cMnO&n?sLIMFr4iCly^$N|6GnyG>$t-@CrlWj*H%%qb)ZS zMQBDrC{IMd17t6#H*>3Lk!DSz+2tjt)2Je|CVkwqsFt_vGOH&-2vA{?EL@O8xDD>c zdE+b`wShqcryh7K;&3>g;4K?xiNQQDDexL70#H=MIPV=AZw(B>ssL|vz%p!hnk?zu zgY%s|t#;m3ms|J3bEqIL>A-~vCyoQA=(U<;Eyke;-ho#LoLa=ODOi#ZBTB=#hYFs; zLu~^yfKIMUi#dibsHfO6IHJZ*OyRg<;t|?+g*Aw_T!E!CnAr@`jw1mG^2Xy!x#y|u zhoXz9Vz*g`+?=AG5jZX(Y;a~w1fxwV&f^?yy`wmvD#w@9rOKv*+wA>96$7rZFg(@?!3!k*%& ztXokt+8ZgVMO`j2o6!0ph@S7h#*!j%1cIA_MIoHyYMT5sN2_L!;Ci}M+9-oRFapA*WX^IW16GF5at}LA5gC1-jNY}&926?NC3ha5fcZ7p}Jv;?Wo-w@yzH1yYAbGll z^NBdq5qD+ilVH;hFMi2U@QK(^@5prPGB`QEP`~9;LWE@tcA;{K7BpY>KTTT4W~HHqk!`v+{YiI(mSnj z93(y5O>lC+PJ^MwhIhwY zs}-W9P69y_I3J*z!=RFuV3I<6tAV#|o;5cZ=3zQQkp`>7p#_|*TS>wBuy=422`U<* z*YG~V&|O8sLQBqr%z~DIWtS26G~9V;iDL@vEEs&@I0p-_Z2V~|y&oO0pch>8IQt;N zzh%pg|V|)?8nBbT$?$(){y-mx`3I1Py_22`l%v&eytH_ z`v(#gYzzU{wSE_F>d2=JL@Tgt6n$N~+65jFV}*VIacC>g`qgkaAV7u4Kh!A1x3%X| z)!w}etc}?bDDfBqyat8~wy?H6Om=gt8!^%u@O! zJen%ITg~ano}&6RtE`Cgl8;ziEtoh!0gP$bvkD?K&L1@8ajPW1S}i7aJWN~llGao) z)Wm7pnNV2Xc>-o`=?ZI87CSTtw+6xtARzESdsc*IkG5`sd&EYZ0%x7#&;Vtbo?K;> z!qt81kZYc@8seM}tPFT{;5CKc6migdA~&(~Uc+en9VPW?_S06q2nZDF17s}N2c-18 z$W#hmfspK-uf=ky-fD1ua2u!+z+LLlAO?*1oS)8LZQaXBHnS=rHQBi^SySlvYHM)R zzyVzZCqS2oh~QY;g2-LW>(G*>K4ZC2NMs$hA(T>_r8Nv~VWbCB{hCnaI;$y%_y&(v zg?CNFaRr>zC|+YxjVMm^An*dc8K?DhsCg?Q29;fIMX6*;aZS4aH;D6`=d8OC=aSgz z7tO^%PMnZS3f}S;tlJ@>U`2s&3ncg6vgR4nD zE2=Z69@shJ_%8HP&_8NutcB~o>^66dPRUbXJ39fdmq>=m&P7!zRF z+INw&XwD6>=G1SB*`hweyEu0#JJ9;$cG9!nvK|OU5dcse9Qu(Ex53gmH%IaN*$kq* zT3akJ3#1IWhqJ*vGm~VwpqE^QAD|*)3O*PbS6B~is&>JXFqXl4qw_UD5{r#34(xNo)XS= zJ2sw3cp`cgeY?XPx@M;v|fV63C?9&AD!5XhrnjuzDmUjpYh4$&l_ zN-FGx5I(24$C`}e5duO4I3$4!h(5~CMX5AW)S0$?WZ|oU%}a9Vf`TFrgR3}1f}b4V zXfBjS-F-fK(rEzD2oxlo!h^YmvH8RcQL=9^uZf^F1Uq73xJ89$`o$A_`Nv;c|fT4rXl#FGXqJ7&GN*&7}vQLkwsA$JUV=9OlWU2^2xghU}yDpIH~d zYlyI{sNigJ9Ih|dpst_81A|B!a~Q+z3}y!j@Mg*wj#h63p?zvM-UElMwpko{MgRy;2N4Zgb7|{gs5nUxVQ%mf z1Fk^mzv9$ zSa#Ul;52dN)_mG9q@;~E=38q`9nOWFn(_{*IC-TRIFNPBx;)Cf)Nph`*aC;xBhTdD zrG6MJ*ZxU?PFkKets0(D4Xaa3BG)C_baa2PN90iU;vF6AmF?8u3VfmsMWQMn4V0eAe&()EACX67(=atrIJ|gpYl+Z=3H@0|RpgDc z`%z&lN-M0=J?2B;pWaH=nf@tws0^9Se{o4*|ULmX$k{^z1N+nX{;E&Gz zRq8b!)u)ug?~oT|8~@MOLu2><&)36a5B$&9BV+&8>~&Ae&$mzWs7p|FQ;INM6hPTr z0J3IU>2D6m7s&!Oe&fPmRgUovA6V8ldUdhfr-}5n(kasMIS-b9d>SD+m3-zAc~vM=-VN z1hshxWi+*3FnM#?4I=tGO)uY5U)AN3Y;MAoORP(BQu?B6=cGb?1J%koWRHxh(@CC# zByZ?4$f1Dg1D3rkuIk(P$(2~~V#g%9B7I#@_RKG*+Ayy;-1vLMC8)w^ps`GkTC8$j zBuN|z(6T1VeH4-p>9xaEj*J#55u~CCat)c4emH-rXY18`1c5wPvQPL=pju84d#RzW zJJQSlbJ&6OfyNR^!msJQL)Bt0OcPH5e3*R<@A7(?u9>9H_nRPYX<$wS_^2!s**D6X zAz5C~cE%*j2mK}weN(T9ssU6`7HBiPKI>oDW4-qzHNk_zo?-!)Cy5)rqkuhesOnx= zEM+fz4l5*>;F!}7o}#WsQUpUFG&HCzPcFHsOg9BpW#tLE@wq8ErksKmcwcHUoM+fJ zHaj!o1-D_G(>DX^j0*ch=Z5S~r>Ttamnd#H(V!I}hmavp9j5wYVC8#3bATMctj1&d z#o_8=FMtC~GTAXK3Z-FmhjV?8)Z!xKh5F!sa+Y2)LfJmBXP##WSpqx~8T0Nk2WYbI z8L0*pc+i^QIK>u;-W(@YL~lD?o#%%$ByFagl=B*1|DR=+9<{SR@}CNLJDQM4nhS2GkjwzIaxzn$ z%__f1H;z^p=yztNI_bb1wmA$1g@91C(0@>Idj4p2jh|zQ7(;BQct>%OytCZdL}%;k z&r_p3qNfXhvOv%YD4fAU9?dAqxdM=s@~mciba-6_M{!N@n4`vbx|mWLj|F zXg~QcJXeS%VNdvt`jXv90gu})hnN@mG8*`^JGmTfVRD~98u6AoVcxniOuEiZn+)ZV#Tt9m73%f^KSv;#b1+E`OM`<@U~hS|s>9DQL}CF-3N(nmBJ)GJ zsT)?~g}eSrH2{Av9$?fk5e!ifAU`&HF)8X*j#%-9kv4HK?sL`!CnYLkB=MrnN5yCD zFX!;ZL!|K#9c%CT9Z3l;ssu2FK%5vxf+o?V`ybR`Ps?Hb?`za0KCv8=sH9P8XP|D< zH&n=`2ryn@uoQBtW5}du!Hfz=nBs`fJ78f}9y$;#Qr_3GPpel!#uV_0rsBq(`u%Pam*H@q~^awPtK zj!>*nR4nN0B`IBT=&OKzA?%ex{h}eUo;u`JqG1@OL_Uo{hP=37 zZ-KQHEd!~KGlYbMMh4LGyfwUziN!EtZF;?^Nh@!&TN7aB4r&2m!(o&Agi*2VcoK$GFLP!#dmGj(aRRA;5Peh?V%gLuq^B zooZ=8U8|Wpfs~jXNuWCyA|&!Lw^@>^wa4A9h86h5lL{9}VkO*BI=t=h?@75yW($3T zP!KUy;`0izZ_<}{0hgJ^xTlR~JJ9XeaknTlasy;Tc@&SamaDg1*$sBkR%-kLp zy`w<@dWWJyWE02WZkc=Y<09$dp=HqnBCt(lf2h#2KO0!rDZ@YTYiQ@;_4U;IRbL@z+dOuUVjq{NVH~8+PsZP)~02DBNV!pLvk=Tcwn<4nsP?r-X%4X_(*^+tR290VRL$k>-C zCBq@Ravk^xG&9~*s&laekWK~XRO$sktD&B#s6;WWLInY~CE|9|OR5h3k_1oGz>riV zzUlD%%FKT-oc6lrd!tm(8m_#KP?`LKI0y2Arxxxq#t(_8DfA_P^r6fE#Kkb3h%Km0 z=td7-#91#f&84rZ$Iw_{b~llx9VUK;C`OK^Sotmg|hVg87ZH86_PWIP$Y85dJznz zS68mp=B=r7#bRHo@133hG%T9jb%b(?eDbxfVedB;xU}0Ik2qi?C@uF^Q zQuSpmhlwL=m@@NvbQV{?r;7cQ$W%x?DfS#vvFzH)bHs;Gt^?KBns3^merVID^)s85 zo+S+hd`7tnbkbBgR5uQ;FVXF1sm}I0@2mAk;(X@Zh6JbJC!dV!#*ft`PlU1s!WeTR zWhw{1-Tf2w@4}047e_?A51K(znuzYNZ2fZ)mBK2)1p|1nS3(CWTRmyXXsCp+nUO=Y znUi|z7Gh%-r54W?Hi{Ba>XfD}>S`3lWaLulhWZq? zCk;9TF9T^5<(6c4ZBo7PCv|% zFw_(s2nJ)37oA~znyfUU8InVuA^1;fm%6i{gv({s@rZr~n7OGl z03Gq}U;Bf4sj!IsPMD_43W|k@sfX=XtNc+!sA&CwLSfW6r?yv_dfGuXM0-wDZ7WYT zFIVCW5vEsCP@&crQ{094 zLBjjEy@x39CtZjwgBTI_O4Axy=EN&;-|c5z>@=ccmTK=GM~+E0hNJ^CBuHTFK$XB! zV~SC5k-y_G!VSo|tf&5@hWbE5@DWnU#n9`*IQ`w7ii;%EhXkPPWL0BE`$tu)`vK~J zgAK3@4vL8l{`0@A6hKK-Iv6w%U{K(LNc=3QH98;?OXQi%H?6;Z*3*7cC)w&>D!|jj zmSRE9fT8dzhP~?!s&l;n(`Z%jWJaR^!;#=EdS;=~fT0=U3;8(06Y-g5ZtZfhJdU$G zE#H67eB;E@mhWZ>+}0(Zrn6j;jZpDZj%5?++nsU3Flb&F5t?IX4_S9~X>~fJ>l_#y z%N3e7X6B}Mam)1M3XP?028ewEzy@fYE+CZ0bGx*@tuS7qj6!mRs2tT|U|ts;{Gxua zJ-V%7aXOMagPkH>FV{#TcRb|Y_ySU3kUMy+(BHw+X zp4{1pm$bYvuPkz2@w9wpPJ3ghk5q{7K@4Qaf>dRfH2aj&!#*W6_KEzr*xBA_0ztxL z!}g^11K{E`ez}WY@wGC5p*YP+s(Ao#pZHwdF;9lzp+ck;$@nI2P2y(i&Qy8HI8s#*7DuB&HwG)RxyyO3 z(L-J?KkQ|u;lnN?^wuh)r#`*Z=5gs%rDwtx*CW!4>@So+|gx-zG$1#PhVeU z9Oa=>Aim=?q0l1|hV+&y!|+jOVmJY)b54Ow`dilG%f>OqGz_6I73DK68A6u6sEctG z#s|Ut_=kFggfz5E@9l0(!n_BM7vV_a41@oS?EYm~8V*T2HUxj9sNd&@<6HZ8+nB%@;J$H-CG{S8 zFTfbRS;S%rk&IAVPdVWfkmXjNy8}xUh~iVFboMg33^EJ zq>!}#^2@EeGv^#~WfvgMC2e3>6MKY?{lf#|uP$oL=@u>L}4>^ej5`9s09? zah{)=5)~D$0TO7QTtUgn;9ufP?pkWpwj>PCJ zN)H^JY^$JscEtD@lOmuL6T(z+lv6{!scYiKa!4=0UJgc%K*$X%_g3{Py>1st>4P(| zh0Tf?*Ly%A(6=GN5&1L+ue~*HoQ5w-gpbl=6LA&&MS}!^q|q0<6#Y~HKWNtmLlTY> z1Q@m(lg5wjdNm8v*5wl~qb~->G7>DZ4yZDkf5EJn|IpnB8)w^|!A5UzNF?fTJY=sh zEUc;+R<$Saw0M=kGqda6u5Rts6OD_#(szliE`>39 zznPn*PakOv6y2-{E5(xH^uNqxEAaIETJKY5aIR2v6gr;`qaDgwhyuu(S- zGmiB@_p>d-GD2}lgyY+-&_ zTn8d;L%;*_5?PcVhFOstbEG=7URmr8BNPKYV!wsJNq{AnxWlNNV5wm5KvCKA<`d2^ zEj~$%#aM~O1sRQ{7Ys9w#|UJGv&ewpXA<;STY>)7#e=L~x{RO!(j!?xe({>{%-OH7ZtRWcSk#`mM!Eieq~S$+ zk1vuZ4DABn6icjX{;CHFU?4mB1w zXPrC8m{$xCf>I3Zh(F-rwD(*iC7?p^If9YzVi=<%-9iTecBSsrP6w>y&VT{pD^wPVoOjUZvk-j1*ri93Gppetr zGsYNQ3%vAbU{N`OUv#(0AKXtMQ33VDu!1m%XA(4ZaI9hZAY)1IaMDq`(%-ejtDUc;<=qfVyZ+>Fb;OTi1z>*4OTRkM^3CqrHv51kEA;-=dASfVt-8U_DfDHO^DcEqT|CbHX}byq|1Uu2nY_& z8w$+Kj{`e|kVMn(3TzX?VU{zV!-h`*gk74_ks2a7+kHC+C}1~|MkWJf4s+19tg)}a z2gHgDEh&@)j$G54%iHG~^!T$34w2Wq_s$lMb#Yj^3!Vh3?R6=Nf(dsKV%^hR&O4jDsXSy?fG)GV|sdK0ji5I;Fr2 zP!SS>gEN}H>Iu;}27x$8NQ~WPMeQ|njp_~%-3|pswnx#BNUYcERvLXgR9CDys1WRu zG^Kde9VI~~9+ME0L=yg9(@l$w-d=JC+(e+#a1Z#H1Fz?YdDJKhQFYJ`13B>^tr-sUiYA=pk4GtgM-Le;Gz#!4?7H1P#kXHsptySmFbz1f>Z4%0_n>@eL+@<^uE& zLrkQ}8TL>XgVWq4 z5%!AF3keyiFTE#FL~M1hA*F>yw?LvW6;3R)%^jB3Uzm!(mt%zcXz=s=Fi(Ys3cx9_ zVRT;nLWaYbd~oD)u=CKR7mZFWs$p_~r} zO?%4YF2Ve1_`-P0O!2`)kh{^s5I#uis?!^#dDPEPD`Ejt*SsXa^YT|F?YXMJXPeE~F}ELzSz=^&JguB{cZVx5nT4)jTbWGGc&gvh#D z-C!Fb4oHYv0w*;L-!){bPmP<}0&GK`iP{tOmz+Q!)Q*-$LcR2c?~E#4v}#a0yL!8^ z2`>mxx$wZ8y5R8X@K?3x%FXnc^AQbTxFH`+lw>Y}Ea4siUccrI!M6w2>W$wRJ^V<9 z@u)^w$%IOj$2(g5b?>v^7zF^`Ee?0>{m!`Aj~taSCImk!3kanjYn^UKy=-ps;z9%^ z(hDbu6AN7w?zd?@M(U<^Mg*b!(e^F7jhK&qhrsz!NNp?=0>H1)O-H7Bc**%md2mY5 zsTSljvDO*3`P~{HvP_hq5H56?CiNkde5zM;N*&{6Yf`w0(E)WFM9^n?uO}7Z{DR}< zR3%#kZpb9`x(=yY#H|pDSQl~gvQeYiZF+K1DpJz&%`B|XomURKj6JPms;tOIV3sa1 zh-!e6qtQEi4$;R~r-s-&D^uPMerYKK^Ftzn%86N6)pM}RK9Xw{=@-35J6rWiY473F zyFH##K9S(D?N~U}LD(2~Vr(9os>S@xahDbr2f!Y@e^*aE^`JW2UXw@-E%J*?oN|E( z1}^~Sw4&FEy5Nk|iTc8!sh<8gl?{cgsHvEEE3mTHT>=eE(ZE37I2K@m~@lA&V1?j>gKif-j0{2 zMpg4V$uQ}NnrsnY@?G4N#oi4cD$5{~y%NZ*kp@5KjXJoRPa?(!>c@%$brp zrJ9_KvIoLg8hxUF+En*oi@)RC_kk-?XI8VwIfF^>fv(WdBsSMQ+}e8|n36iT8oHfb z&j}+EW*VA(*!p`*u*_gHJ!rFJ~Onm8^Ba8u++goNCRzD zmXb67TBo}&NTrSlj@^=98M5^ubV+`=08YnG-FMiVu1;-L9v*~LqtNTT7K={P-JeVK z@rq!UydED8*bVx<8}h>f#S!sEi0c~uz6X^aMjx^|{zVsXt9yYs6d8RV z;CdyhME{f@r9m9fG@t|kNHBeyJ4*I|aZnl^@JGzLJwM8?`G8o{BZwxvX66oeRQfyt zkxEmj0C_Z6+8lS3=S5>h#91_XkC-v-j*@MG!jX4Ej_~6j z_qw+hkt~ECHv)5@LP=!r%MT}T5|DQ=tEgj=q5Jd0Y1X=YBDyvbvE&1K-Re}|BFY+q zBW?k*;%r!Ndm%-~C5}USvXO;RBN4&oId4VX909MupGP8(h-kihU9xAHI7+#Pc7U3T4p{Sz(?IHl1&J(0}2In=ZLdbItnao3a_KVE2*rx>) z6Ox{C;9++ZwLM>($`}6>Sp6gJCBP1#3g~r_V>zRHd^A6th)`0J(Lf8JKT1EAAC^^z z5RU$Rs14)s$MeG&HzoNA;2q${I06f`xt9AtIYy$4V1UV|%v$7*g2N(p=F^}Okg6_r zM`^LbffB}{2EJkimguJSvd!RVqSA_nzK4F$TJHY+G-ZN_#>uO(>;h&wSEcYV zsS=q~GAhLwy*V&^(v~<8eBQk-bs#H^OoqP>z8hJcALdMDy-=%3 zhmb(x1$UVAhZzEMq&FMHP3}c^7-vgR3S*)L1zkA1=9i0*FwxhIvIq^jN&dLvb#4UF z3P}a6@YwT+v(`B?U5vzDfND{@V_q=zb+4xG;3wdCR?LQIh@ly*m)(6$e+4nAK@>4n zIrA0yI934LQ99p=sE9*ny?YZZ9e#6!h8BRVG$jHgad!@iHgI8N6X?1CdtY;h*$MQR zLMtupUufXv#Kt1iXZ=@1k z5!9hu!%gb+Jwnj)=e}{5x~bWb^7*+=7X1#~6JZ~*>T`XY5j!4!%n4?MiW|OwpA-n$ z(|4pUEEE+pas}!9PLHi*GV?*-K{~j-zD9TbF4d9d?or$#fFevSRabaZ-=TU%BO3Ax zzDrg3@bsgxL#u`_2MovD+*dDe98^;=Y+~lO6m{S?h##cD=7A$X|4^^pm8vZ!f;+(z agp^JLX}#yW)N!=^KlC>2<94R%+x number; export const sqlite3_os_end: () => number; export const sqlite3_os_init: () => number; export const wasm_bindgen__convert__closures_____invoke__ha1c2fa93df0107f3: (a: number, b: number, c: any) => [number, number]; -export const wasm_bindgen__convert__closures_____invoke__h38d884a456ef1afe: (a: number, b: number, c: any) => [number, number]; +export const wasm_bindgen__convert__closures_____invoke__h4381d8e749fe46cf: (a: number, b: number, c: any) => [number, number]; export const wasm_bindgen__convert__closures_____invoke__h2cf3f4cce3b29948: (a: number, b: number, c: any, d: any) => void; export const wasm_bindgen__convert__closures_____invoke__ha7903b6e296dd8f4: (a: number, b: number, c: any) => void; export const wasm_bindgen__convert__closures_____invoke__ha1b480b83daa641f: (a: number, b: number) => void; diff --git a/crates/yaak-web/src/lib.rs b/crates/yaak-wasm/src/lib.rs similarity index 99% rename from crates/yaak-web/src/lib.rs rename to crates/yaak-wasm/src/lib.rs index d4afd43e..45704162 100644 --- a/crates/yaak-web/src/lib.rs +++ b/crates/yaak-wasm/src/lib.rs @@ -478,7 +478,7 @@ impl TemplateCallback for NoPluginsCallback { /// Resolve and render a request for sending, exactly as the desktop does before it puts the /// request on the network: the environment chain, inherited headers and auth, request /// settings, the cookie jar. Nothing here touches a socket. What comes back is what the tab -/// posts to the send proxy. +/// posts to the Yaak server. /// /// Refuses, with a message the user can act on, when the request needs something this host /// doesn't have: an authentication plugin, or a template function. diff --git a/crates/yaak-web/pkg/package.json b/crates/yaak-web/pkg/package.json deleted file mode 100644 index cace5c1b..00000000 --- a/crates/yaak-web/pkg/package.json +++ /dev/null @@ -1,17 +0,0 @@ -{ - "name": "yaak-web", - "type": "module", - "version": "0.1.0", - "files": [ - "yaak_web_bg.wasm", - "yaak_web.js", - "yaak_web_bg.js", - "yaak_web.d.ts" - ], - "main": "yaak_web.js", - "types": "yaak_web.d.ts", - "sideEffects": [ - "./yaak_web.js", - "./snippets/*" - ] -} \ No newline at end of file diff --git a/crates/yaak-web/pkg/yaak_web.js b/crates/yaak-web/pkg/yaak_web.js deleted file mode 100644 index d6309774..00000000 --- a/crates/yaak-web/pkg/yaak_web.js +++ /dev/null @@ -1,6 +0,0 @@ -import init from "./yaak_web_bg.wasm?init"; -export * from "./yaak_web_bg.js"; -import * as bg from "./yaak_web_bg.js"; -const instance = await init({ "./yaak_web_bg.js": bg }); -bg.__wbg_set_wasm(instance.exports); -instance.exports.__wbindgen_start(); diff --git a/greptile.json b/greptile.json index 60f15046..f99d7089 100644 --- a/greptile.json +++ b/greptile.json @@ -1,3 +1,3 @@ { - "ignorePatterns": "crates/yaak-templates/pkg/**\ncrates/yaak-web/pkg/**\n**/bindings/gen_*.ts\npackage-lock.json\nCargo.lock" + "ignorePatterns": "crates/yaak-templates/pkg/**\ncrates/yaak-wasm/pkg/**\n**/bindings/gen_*.ts\npackage-lock.json\nCargo.lock" } diff --git a/package-lock.json b/package-lock.json index 44eb040d..f288fd6b 100644 --- a/package-lock.json +++ b/package-lock.json @@ -67,10 +67,10 @@ "crates/yaak-sse", "crates/yaak-sync", "crates/yaak-templates", - "crates/yaak-web", + "crates/yaak-wasm", "crates/yaak-ws", "crates-proxy/yaak-proxy-lib", - "crates-server/yaak-send-proxy", + "crates-server/yaak-web", "apps/yaak-client", "apps/yaak-proxy" ], @@ -273,8 +273,8 @@ "name": "@yaakapp-internal/proxy-lib", "version": "1.0.0" }, - "crates-server/yaak-send-proxy": { - "name": "@yaakapp-internal/send-proxy", + "crates-server/yaak-web": { + "name": "@yaakapp-internal/web", "version": "1.0.0" }, "crates-tauri/yaak-app-client": { @@ -335,8 +335,8 @@ "rimraf": "^6.1.2" } }, - "crates/yaak-web": { - "name": "@yaakapp-internal/web", + "crates/yaak-wasm": { + "name": "@yaakapp-internal/wasm", "version": "1.0.0", "devDependencies": { "rimraf": "^6.1.2" @@ -5650,10 +5650,6 @@ "resolved": "crates/common/yaak-rpc-schema", "link": true }, - "node_modules/@yaakapp-internal/send-proxy": { - "resolved": "crates-server/yaak-send-proxy", - "link": true - }, "node_modules/@yaakapp-internal/sse": { "resolved": "crates/yaak-sse", "link": true @@ -5686,8 +5682,12 @@ "resolved": "packages/ui", "link": true }, + "node_modules/@yaakapp-internal/wasm": { + "resolved": "crates/yaak-wasm", + "link": true + }, "node_modules/@yaakapp-internal/web": { - "resolved": "crates/yaak-web", + "resolved": "crates-server/yaak-web", "link": true }, "node_modules/@yaakapp-internal/ws": { @@ -15810,7 +15810,7 @@ "@tauri-apps/plugin-os": "^2.3.2", "@yaakapp-internal/models": "^1.0.0", "@yaakapp-internal/rpc-schema": "^1.0.0", - "@yaakapp-internal/send-proxy": "^1.0.0", + "@yaakapp-internal/wasm": "^1.0.0", "@yaakapp-internal/web": "^1.0.0" } }, diff --git a/package.json b/package.json index 350d77fe..a00186a4 100644 --- a/package.json +++ b/package.json @@ -66,10 +66,10 @@ "crates/yaak-sse", "crates/yaak-sync", "crates/yaak-templates", - "crates/yaak-web", + "crates/yaak-wasm", "crates/yaak-ws", "crates-proxy/yaak-proxy-lib", - "crates-server/yaak-send-proxy", + "crates-server/yaak-web", "apps/yaak-client", "apps/yaak-proxy" ], diff --git a/packages/platform/package.json b/packages/platform/package.json index 751cb0a5..2beea84e 100644 --- a/packages/platform/package.json +++ b/packages/platform/package.json @@ -11,8 +11,8 @@ "dependencies": { "@yaakapp-internal/models": "^1.0.0", "@yaakapp-internal/rpc-schema": "^1.0.0", - "@yaakapp-internal/send-proxy": "^1.0.0", "@yaakapp-internal/web": "^1.0.0", + "@yaakapp-internal/wasm": "^1.0.0", "@tauri-apps/api": "^2.11.0", "@tauri-apps/plugin-clipboard-manager": "^2.3.2", "@tauri-apps/plugin-dialog": "^2.7.1", diff --git a/packages/platform/src/web/README.md b/packages/platform/src/web/README.md index fdebbad8..6f6cf3d5 100644 --- a/packages/platform/src/web/README.md +++ b/packages/platform/src/web/README.md @@ -24,9 +24,9 @@ installs the Tauri host exactly as before. ``` tab (index.ts, commands.ts) ──MessagePort──▶ worker.ts ──▶ @yaakapp-internal/web (wasm) - │ ◀── model_writes ── crates/yaak-web → yaak-models → SQLite + │ ◀── model_writes ── crates/yaak-wasm → yaak-models → SQLite │ └─ pages in IndexedDB - └── send.ts ──POST rendered request──▶ yaak-send-proxy (crates-server) ──▶ the internet + └── send.ts ──POST rendered request──▶ yaak-web (crates-server) ──▶ the internet ◀── NDJSON: events, response, body, cookies ── ``` @@ -35,14 +35,14 @@ tab (index.ts, commands.ts) ──MessagePort──▶ worker.ts ──▶ @yaak | `index.ts` | The `Platform` implementation. | | `commands.ts` | The command table: model commands forward to the worker; the rest is fixed answers and refusals-with-a-reason. | | `connection.ts` | A tab's end of the wire: request/response over a `MessagePort`, event delivery, and the tab's identity (`label`). | -| `send.ts` | Sending: the worker renders (`prepare_http_send`), the proxy executes, this file stores what comes back where the desktop stores it. | -| `proxy.ts` | The proxy's location and wire shapes, mirrored by hand from `crates-server/yaak-send-proxy/src/wire.rs`. | +| `send.ts` | Sending: the worker renders (`prepare_http_send`), the server executes, this file stores what comes back where the desktop stores it. | +| `server.ts` | Where the Yaak server is, and the wire shapes it speaks (generated from `crates-server/yaak-web/src/wire.rs`). | | `worker.ts` | The process that owns the database. Loads the wasm, opens the DB once, answers each port, fans `model_writes` out to every port. | | `protocol.ts` | The message shapes both sides import. | | `errors.ts` | `UnsupportedCommandError`, the structured refusal. | | `storage.ts` | `navigator.storage.persist()`. | -The Rust side is `crates/yaak-web` (`@yaakapp-internal/web`): `boot()`, +The Rust side is `crates/yaak-wasm` (`@yaakapp-internal/wasm`): `boot()`, `rpc(cmd, payload, label)` returning `{ result, events }`, blob get/put, and `prepare_http_send(payload)` — the database half of a send (environment chain, inherited headers and auth, request settings, cookie jar, rendering), which is @@ -85,7 +85,7 @@ Behaviours worth knowing before changing anything: | Group | Commands | | --- | --- | | Models | `models_workspace_models`, `models_upsert`, `models_delete`, `models_duplicate`, `models_get_settings`, `models_get_graphql_introspection`, `models_upsert_graphql_introspection`, `models_grpc_events`, `models_websocket_events` | -| Sending | `cmd_send_http_request` (through the send proxy; see below) | +| Sending | `cmd_send_http_request` (through the Yaak server; see below) | | App | `cmd_metadata`, `cmd_get_workspace_meta`, `cmd_default_headers`, `cmd_get_themes`, `cmd_check_for_updates`, `cmd_dismiss_notification`, `cmd_plugin_init_errors` | | Bodies | `cmd_http_response_body`, `cmd_http_response_body_path`, `cmd_http_request_body`, `cmd_get_http_response_events`, `cmd_get_sse_events` | | Plugin surfaces (empty results) | `cmd_http_request_actions`, `cmd_websocket_request_actions`, `cmd_grpc_request_actions`, `cmd_workspace_actions`, `cmd_folder_actions`, `cmd_template_function_summaries`, `cmd_get_http_authentication_summaries`, `cmd_get_http_authentication_config` | @@ -187,8 +187,8 @@ other's writes for an echo of their own and drop them. A page cannot see a response the way a desktop app can — CORS exposes a handful of headers, redirects are followed silently, there is no timeline — so the -network half of a send runs on a small stateless proxy, -`crates-server/yaak-send-proxy`. This layer stays the only place data lives: +network half of a send runs on a small stateless server, +`crates-server/yaak-web`. This layer stays the only place data lives: 1. `send.ts` creates the `http_response` row (state `initialized`), as the desktop does, so anything that goes wrong lands in the response pane. @@ -198,7 +198,7 @@ network half of a send runs on a small stateless proxy, with `yaak_models::render::render_http_request`. Variables (`${[ name ]}`) render here with no plugins involved. 3. The rendered request, the settings and the jar's cookies are POSTed to the - proxy. It streams back timeline events, the response head, body chunks and a + server. It streams back timeline events, the response head, body chunks and a terminal frame carrying the jar as the send left it. 4. Each frame is written where the desktop writes it: the response row as it progresses, `http_response_event` rows for the timeline (which is why @@ -210,10 +210,18 @@ authentication is none, or an inline header. Sending a request that needs a template *function* (`${[ timestamp() ]}`) or an authentication plugin (bearer, basic, OAuth, …) is refused before anything leaves the tab, with a message naming what it needs; those light up when plugins run in the browser. Requests with a -file body or multipart file fields are refused by the proxy (it has no access to -your files, and must not read its own). And a request to `localhost` or a LAN -address can't work from a browser: the proxy runs elsewhere and refuses private -ranges outright — reaching your own machine's APIs is what the desktop app is for. +file body or multipart file fields are refused by the server (it has no access to +your files, and must not read its own). And on a public instance a request to +`localhost` or a LAN address can't work: the server runs elsewhere and refuses +private ranges outright — that is what the desktop app is for. A self-hosted +server on your own network can be started with `--allow-private-networks`, which +is the one case where those addresses are the user's to reach. -The proxy URL is `VITE_YAAK_SEND_PROXY_URL` at build time, defaulting to -`http://127.0.0.1:9227` (see `proxy.ts`). Run one with `cargo run -p yaak-send-proxy`. +**Where the tab sends** (`server.ts`): a production build posts to `/v1/http/send` +on its own origin, because the server can serve the app itself +(`yaak-web --serve dist/apps/yaak-client`, which is what the +`ghcr.io/mountain-loop/yaak-web` image runs) — same origin, so no CORS and +nothing to configure. A dev build falls back to `http://127.0.0.1:9227`, since +the Vite server is a different origin and serves no `/v1`; run one with +`cargo run -p yaak-web`. `VITE_YAAK_WEB_URL` overrides both, for a +deployment that keeps the app and the server apart. diff --git a/packages/platform/src/web/commands.ts b/packages/platform/src/web/commands.ts index a2f1dd71..88137d5c 100644 --- a/packages/platform/src/web/commands.ts +++ b/packages/platform/src/web/commands.ts @@ -71,7 +71,7 @@ const HANDLERS: Partial> = { /* ------------------------------- sending ------------------------------- */ - // The tab renders and stores; a stateless proxy puts the bytes on the wire. + // The tab renders and stores; a stateless server puts the bytes on the wire. // See send.ts for the whole shape of it. cmd_send_http_request: (payload, db) => { const requestId = str(payload, "requestId"); @@ -249,7 +249,7 @@ const HTTP_AUTHENTICATION_SUMMARIES = [ * while the first is a slice away. */ const DECLINED: Partial> = { - // Saved requests send through the proxy (see send.ts). Ephemeral sends — the + // Saved requests send through the server (see send.ts). Ephemeral sends — the // ones nothing stores, used for GraphQL introspection — take the same road but // return the body inline; not wired yet. cmd_send_ephemeral_request: ["Sending unsaved requests isn't available in the browser yet", null], @@ -266,7 +266,7 @@ const DECLINED: Partial((id) => ({ type: "rpc", id, cmd, payload, label: this.label })); } - /** See `prepare_http_send` in crates/yaak-web: the database half of a send. */ + /** See `prepare_http_send` in crates/yaak-wasm: the database half of a send. */ prepareHttpSend(payload: unknown): Promise { return this.request((id) => ({ type: "prepare_http_send", id, payload })); } diff --git a/packages/platform/src/web/index.ts b/packages/platform/src/web/index.ts index 7e97f8a4..4835afaa 100644 --- a/packages/platform/src/web/index.ts +++ b/packages/platform/src/web/index.ts @@ -7,7 +7,7 @@ * the origin, so two tabs stay coherent for the same reason two desktop windows * do: one process holds the data and pushes every write to all of them. * - * Sending goes through a small stateless proxy, because a page cannot see a + * Sending goes through a small stateless server, because a page cannot see a * response the way a desktop app can (see send.ts). What a page genuinely * cannot do is not faked: there is no file dialog, no second window, no * clipboard read without a prompt. Those report false through `capabilities` @@ -33,7 +33,7 @@ import { requestPersistence } from "./storage"; /** What this host can do, reported honestly. */ function capabilitiesFor(): PlatformCapabilities { return { - // Through the send proxy: the tab renders, the proxy executes, the tab + // Through the Yaak server: the tab renders, the server executes, the tab // stores. Requests needing plugin auth or template functions are refused // with the reason until plugins run here. httpSending: true, @@ -42,11 +42,11 @@ function capabilitiesFor(): PlatformCapabilities { git: false, sync: false, // Certificates and proxies are decided by whoever puts the bytes on the - // wire, and the send proxy uses its own. + // wire, and the Yaak server uses its own. tlsOptions: false, cookieJar: true, localFiles: false, - // The proxy streams the engine's events back and the sender stores them. + // The server streams the engine's events back and the sender stores them. timeline: true, // Whether the host can put a *second window* on this data on demand — what // `cmd_new_child_window` does for Settings and workspace switching. A tab diff --git a/packages/platform/src/web/proxy.ts b/packages/platform/src/web/proxy.ts deleted file mode 100644 index e886c9f4..00000000 --- a/packages/platform/src/web/proxy.ts +++ /dev/null @@ -1,71 +0,0 @@ -/** - * The wire to the send proxy: where it is, and how to read what comes back. - * - * The shapes themselves are generated from `crates-server/yaak-send-proxy/src/wire.rs` - * into `@yaakapp-internal/send-proxy`, so the two sides cannot drift silently. - */ - -import type { Frame } from "@yaakapp-internal/send-proxy"; - -/* ------------------------------- location -------------------------------- */ - -/** - * Where the tab sends. Build-time configuration for now: `VITE_YAAK_SEND_PROXY_URL` - * (Vite exposes `VITE_*` to the bundle), defaulting to a proxy on this machine at - * its default port. A per-user setting can replace this later without touching - * the callers, which only ever ask for the URL. - */ -export function proxyBaseUrl(): string { - const env = (import.meta as unknown as { env?: Record }).env; - const configured = env?.VITE_YAAK_SEND_PROXY_URL?.trim(); - return (configured || "http://127.0.0.1:9227").replace(/\/+$/, ""); -} - -export function proxySendUrl(): string { - return `${proxyBaseUrl()}/v1/http/send`; -} - -let identity: Promise | null = null; - -/** - * Who does the sending, for the timeline: `yaak-send-proxy 0.1.0 at http://…`. - * Asked of `/v1/health` once per page load; if the proxy can't be reached the - * URL alone is the answer, and the send itself will say why shortly after. - */ -export function proxyIdentity(): Promise { - identity ??= fetch(`${proxyBaseUrl()}/v1/health`) - .then((res) => res.json() as Promise<{ version?: string }>) - .then((health) => `yaak-send-proxy ${health.version ?? ""} at ${proxyBaseUrl()}`.replace(" ", " ")) - .catch(() => { - identity = null; // try again next send - return `send proxy at ${proxyBaseUrl()}`; - }); - return identity; -} - -/** - * Yield frames from an NDJSON stream as they arrive. A partial trailing line is - * held until its newline comes; anything left when the stream ends is dropped, - * because a frame without its newline is a frame the proxy didn't finish writing. - */ -export async function* readFrames(stream: ReadableStream): AsyncGenerator { - const reader = stream.getReader(); - const decoder = new TextDecoder(); - let buffer = ""; - try { - while (true) { - const { value, done } = await reader.read(); - if (done) break; - buffer += decoder.decode(value, { stream: true }); - let newline = buffer.indexOf("\n"); - while (newline !== -1) { - const line = buffer.slice(0, newline); - buffer = buffer.slice(newline + 1); - if (line.trim() !== "") yield JSON.parse(line) as Frame; - newline = buffer.indexOf("\n"); - } - } - } finally { - reader.releaseLock(); - } -} diff --git a/packages/platform/src/web/send.ts b/packages/platform/src/web/send.ts index 7b970280..061abc27 100644 --- a/packages/platform/src/web/send.ts +++ b/packages/platform/src/web/send.ts @@ -3,7 +3,7 @@ * * A tab can't see a response the way the desktop can — CORS hides most headers, * redirects are followed silently, there is no timeline — so the network half of - * a send happens on a small stateless proxy (`crates-server/yaak-send-proxy`). + * a send happens on a small stateless server (`crates-server/yaak-web`). * Everything else happens here, against this tab's own database, in the same * order the desktop does it: * @@ -11,13 +11,13 @@ * 2. resolve and render the request in the worker (`prepare_http_send`: the * environment chain, inherited headers and auth, request settings, cookie * jar — the desktop's `HttpSendInputs`, in Rust, on the same model layer); - * 3. POST the rendered request to the proxy and consume its stream: timeline + * 3. POST the rendered request to the server and consume its stream: timeline * events, the response head, body chunks, and a terminal frame; * 4. write what comes back where the desktop writes it — the response row as * it progresses, `http_response_event` rows for the timeline, the body - * blob under the response id, the cookie jar with the proxy's changes. + * blob under the response id, the cookie jar with the server's changes. * - * The proxy keeps nothing. Every byte it sees comes from this tab and every + * The server keeps nothing. Every byte it sees comes from this tab and every * byte it returns is stored by this tab. */ @@ -31,9 +31,9 @@ import type { HttpResponseEventData, HttpSendSettings, } from "@yaakapp-internal/models"; -import type { Frame, SendRequest } from "@yaakapp-internal/send-proxy"; +import type { Frame, SendRequest } from "@yaakapp-internal/web"; import type { WorkerConnection } from "./connection"; -import { proxyIdentity, proxySendUrl, readFrames } from "./proxy"; +import { serverIdentity, serverSendUrl, readFrames } from "./server"; /* -------------------------------- shapes --------------------------------- */ @@ -48,7 +48,7 @@ type ResponseRow = Pick & type ResponsePatch = Partial; -/** What `prepare_http_send` (crates/yaak-web) hands back. */ +/** What `prepare_http_send` (crates/yaak-wasm) hands back. */ interface PreparedHttpSend { request: HttpRequest; settings: HttpSendSettings; @@ -68,7 +68,7 @@ export async function sendHttpRequest( cookieJarId: string | null, ): Promise { // The response row exists before anything can go wrong, as on the desktop, so - // a failure to render or to reach the proxy lands in the response pane as + // a failure to render or to reach the server lands in the response pane as // that response's error rather than as a toast that names no request. const workspaceId = await workspaceIdOfRequest(db, requestId); const response = new ResponseWriter(db, { model: "http_response", requestId, workspaceId }); @@ -107,7 +107,7 @@ async function runSend( // request through a proxy shows a different origin to the server than the // user's machine, and this is where that should be visible. const timeline = new TimelineWriter(db, response.id, response.workspaceId); - timeline.push([{ type: "info", message: `Executed by ${await proxyIdentity()}` }]); + timeline.push([{ type: "info", message: `Executed by ${await serverIdentity()}` }]); timeline.push(prepared.settingEvents); const body: SendRequest = { @@ -116,19 +116,19 @@ async function runSend( cookies: prepared.cookieJar?.cookies ?? null, }; const startedAt = performance.now(); - const res = await fetch(proxySendUrl(), { + const res = await fetch(serverSendUrl(), { method: "POST", headers: { "content-type": "application/json" }, body: JSON.stringify(body), signal, }).catch((err: unknown) => { if (signal.aborted) throw err; - throw new Error(`Couldn't reach the send proxy at ${proxySendUrl()}: ${errorMessage(err)}`); + throw new Error(`Couldn't reach the Yaak server at ${serverSendUrl()}: ${errorMessage(err)}`); }); if (!res.ok) { // A refusal, not a failed send: bad destination, rate limit, a body the - // proxy can't build. It comes as JSON with the reason. + // server can't build. It comes as JSON with the reason. const text = await res.text(); let reason = text; try { @@ -136,9 +136,9 @@ async function runSend( } catch { /* not JSON; the text is the reason */ } - throw new Error(reason || `The send proxy answered ${res.status}`); + throw new Error(reason || `The Yaak server answered ${res.status}`); } - if (res.body == null) throw new Error("The send proxy sent no body"); + if (res.body == null) throw new Error("The Yaak server sent no body"); const chunks: Uint8Array[] = []; let received = 0; @@ -175,12 +175,12 @@ async function runSend( if (terminal != null) break; } - // Everything the proxy said about the timeline is in the database before the + // Everything the server said about the timeline is in the database before the // response is marked closed, so a reader that wakes on "closed" sees all of it. await timeline.flush(); if (terminal == null) { - throw new Error("The send proxy closed the stream without finishing"); + throw new Error("The Yaak server closed the stream without finishing"); } // Cookies come back on both outcomes: a hop before the failing one may have @@ -196,7 +196,7 @@ async function runSend( // The body is written under the response id, which is how every reader — // `cmd_http_response_body`, the image viewer, the download button — asks for // it. One write, once the whole body is here: the worker's blob store has no - // append, and a body larger than memory is over the proxy's cap anyway. + // append, and a body larger than memory is over the server's cap anyway. await db.blobPut(response.id, concat(chunks, received)); await response.finish({ contentLength: terminal.contentLength, diff --git a/packages/platform/src/web/server.ts b/packages/platform/src/web/server.ts new file mode 100644 index 00000000..1ce57624 --- /dev/null +++ b/packages/platform/src/web/server.ts @@ -0,0 +1,83 @@ +/** + * The wire to the Yaak server: where it is, and how to read what comes back. + * + * The shapes themselves are generated from `crates-server/yaak-web/src/wire.rs` + * into `@yaakapp-internal/web`, so the two sides cannot drift silently. + */ + +import type { Frame } from "@yaakapp-internal/web"; + +/* ------------------------------- location -------------------------------- */ + +/** + * Where the tab sends. + * + * Empty means "this origin": the server can serve the app itself + * (`yaak-web --serve`), and then a send is a request to a path on the + * page's own origin — no CORS, and nothing for a self-hoster to configure. + * + * `VITE_YAAK_WEB_URL` overrides it at build time, for a deployment that + * keeps the two apart. The dev server is one of those: it serves the app on its + * own origin and knows nothing about `/v1`, so a dev build falls back to a server + * running locally (`cargo run -p yaak-web`). + */ +export function serverBaseUrl(): string { + const env = (import.meta as unknown as { env?: Record }).env; + const configured = env?.VITE_YAAK_WEB_URL?.trim(); + if (configured) return configured.replace(/\/+$/, ""); + return env?.DEV ? "http://127.0.0.1:9227" : ""; +} + +export function serverSendUrl(): string { + return `${serverBaseUrl()}/v1/http/send`; +} + +let identity: Promise | null = null; + +/** The server's location as a person reads it, since "" means "this origin". */ +function serverLocation(): string { + return serverBaseUrl() || globalThis.location?.origin || "this origin"; +} + +/** + * Who does the sending, for the timeline: `yaak-web 0.1.0 at http://…`. + * Asked of `/v1/health` once per page load; if the server can't be reached the + * URL alone is the answer, and the send itself will say why shortly after. + */ +export function serverIdentity(): Promise { + identity ??= fetch(`${serverBaseUrl()}/v1/health`) + .then((res) => res.json() as Promise<{ version?: string }>) + .then((health) => `yaak-web ${health.version ?? ""} at ${serverLocation()}`.replace(" ", " ")) + .catch(() => { + identity = null; // try again next send + return `Yaak server at ${serverLocation()}`; + }); + return identity; +} + +/** + * Yield frames from an NDJSON stream as they arrive. A partial trailing line is + * held until its newline comes; anything left when the stream ends is dropped, + * because a frame without its newline is a frame the server didn't finish writing. + */ +export async function* readFrames(stream: ReadableStream): AsyncGenerator { + const reader = stream.getReader(); + const decoder = new TextDecoder(); + let buffer = ""; + try { + while (true) { + const { value, done } = await reader.read(); + if (done) break; + buffer += decoder.decode(value, { stream: true }); + let newline = buffer.indexOf("\n"); + while (newline !== -1) { + const line = buffer.slice(0, newline); + buffer = buffer.slice(newline + 1); + if (line.trim() !== "") yield JSON.parse(line) as Frame; + newline = buffer.indexOf("\n"); + } + } + } finally { + reader.releaseLock(); + } +} diff --git a/packages/platform/src/web/worker.ts b/packages/platform/src/web/worker.ts index bd6d75e7..8998b541 100644 --- a/packages/platform/src/web/worker.ts +++ b/packages/platform/src/web/worker.ts @@ -26,7 +26,7 @@ import { DB_LOCK_NAME, type FromWorker, type ToWorker } from "./protocol"; * download and compile — and the tab can therefore tell "this worker is dead" * from "this worker is busy" with a short timeout. */ -type Engine = typeof import("@yaakapp-internal/web"); +type Engine = typeof import("@yaakapp-internal/wasm"); let engine: Engine | null = null; const ports = new Set(); @@ -96,7 +96,7 @@ function bootOnce(): Promise { booted = (async () => { await acquireDatabaseLock(); - const loaded = await import("@yaakapp-internal/web"); + const loaded = await import("@yaakapp-internal/wasm"); await loaded.boot(); engine = loaded; })(); diff --git a/vite.config.ts b/vite.config.ts index fd992ad0..5042e3e1 100644 --- a/vite.config.ts +++ b/vite.config.ts @@ -5,7 +5,7 @@ export default defineConfig({ "*": "vp check --fix", }, lint: { - ignorePatterns: ["npm/**", "crates/yaak-templates/pkg/**", "crates/yaak-web/pkg/**", "**/bindings/gen_*.ts"], + ignorePatterns: ["npm/**", "crates/yaak-templates/pkg/**", "crates/yaak-wasm/pkg/**", "**/bindings/gen_*.ts"], options: { typeAware: true, },