diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 0e3f65f336..7c2a397170 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -8,9 +8,13 @@ on: merge_group: workflow_dispatch: +# A newer push to the same ref cancels the run still in progress, main included. +# A full run costs about 200 runner-minutes against the org's 20 concurrent +# jobs, and a superseded main run only answers a question the newer commit +# answers again. concurrency: group: ci-${{ github.workflow }}-${{ github.ref }} - cancel-in-progress: ${{ github.event_name == 'pull_request' }} + cancel-in-progress: true env: # CI does not use the CUDA execution provider, and the onnxruntime-node @@ -54,10 +58,10 @@ jobs: - name: Validate CI contracts run: node --test scripts/ci-workflow.test.mjs scripts/daemon-launch-contract.test.mjs scripts/sync-fdroid-changelogs.test.mjs scripts/upload-release-assets.test.mjs - format: - name: format + quality: + name: quality needs: changes - if: ${{ !cancelled() && (needs.changes.outputs.full != 'false' || needs.changes.outputs.format != 'false') }} + if: ${{ !cancelled() && (needs.changes.outputs.full != 'false' || needs.changes.outputs.format != 'false' || needs.changes.outputs.quality != 'false' || needs.changes.outputs.relay != 'false' || needs.changes.outputs.sdk != 'false') }} runs-on: ubuntu-latest steps: - uses: actions/checkout@v4 @@ -68,36 +72,67 @@ jobs: cache: "npm" - name: Install dependencies + id: install run: node scripts/npm-retry.mjs ci + # Explicit status checks keep independent domains running after a failure. + # A failed step still fails quality; no continue-on-error or success shim. - name: Check formatting + if: ${{ !cancelled() && steps.install.outcome == 'success' && (needs.changes.outputs.full != 'false' || needs.changes.outputs.format != 'false') }} run: npm run format:check - lint: - name: lint - needs: changes - if: ${{ !cancelled() && (needs.changes.outputs.full != 'false' || needs.changes.outputs.quality != 'false') }} - runs-on: ubuntu-latest - steps: - - uses: actions/checkout@v4 - - - uses: actions/setup-node@v4 - with: - node-version: "22" - cache: "npm" - - - name: Install dependencies - run: node scripts/npm-retry.mjs ci - - name: Lint lockfile + if: ${{ !cancelled() && steps.install.outcome == 'success' && (needs.changes.outputs.full != 'false' || needs.changes.outputs.quality != 'false') }} run: npx --yes lockfile-lint --path package-lock.json --type npm --allowed-hosts npm --validate-https --validate-integrity - name: Verify dependency signatures + if: ${{ !cancelled() && steps.install.outcome == 'success' && (needs.changes.outputs.full != 'false' || needs.changes.outputs.quality != 'false') }} run: npm audit signatures - name: Lint + if: ${{ !cancelled() && steps.install.outcome == 'success' && (needs.changes.outputs.full != 'false' || needs.changes.outputs.quality != 'false') }} run: npm run lint + - name: Test lint rules + if: ${{ !cancelled() && steps.install.outcome == 'success' && (needs.changes.outputs.full != 'false' || needs.changes.outputs.quality != 'false') }} + run: node --test scripts/oxlint/paseo-plugin.test.mjs + + - name: Build relay + if: ${{ !cancelled() && steps.install.outcome == 'success' && (needs.changes.outputs.full != 'false' || needs.changes.outputs.relay != 'false') }} + run: npm run build:relay + + - name: Run relay tests + if: ${{ !cancelled() && steps.install.outcome == 'success' && (needs.changes.outputs.full != 'false' || needs.changes.outputs.relay != 'false') }} + run: npm run test --workspace=@getpaseo/relay + + - name: Build client dependencies + if: ${{ !cancelled() && steps.install.outcome == 'success' && (needs.changes.outputs.full != 'false' || needs.changes.outputs.sdk != 'false') }} + run: npm run build:relay && npm run build:client + + - name: Build plugin SDK + if: ${{ !cancelled() && steps.install.outcome == 'success' && (needs.changes.outputs.full != 'false' || needs.changes.outputs.sdk != 'false') }} + run: npm run build:plugin + + - name: Run plugin SDK tests + if: ${{ !cancelled() && steps.install.outcome == 'success' && (needs.changes.outputs.full != 'false' || needs.changes.outputs.sdk != 'false') }} + run: npm run test --workspace=@getpaseo/plugin + + - name: Run protocol tests + if: ${{ !cancelled() && steps.install.outcome == 'success' && (needs.changes.outputs.full != 'false' || needs.changes.outputs.sdk != 'false') }} + run: npm run test --workspace=@getpaseo/protocol + + - name: Run client tests + if: ${{ !cancelled() && steps.install.outcome == 'success' && (needs.changes.outputs.full != 'false' || needs.changes.outputs.sdk != 'false') }} + run: npm run test --workspace=@getpaseo/client + + - name: Run highlight tests + if: ${{ !cancelled() && steps.install.outcome == 'success' && (needs.changes.outputs.full != 'false' || needs.changes.outputs.sdk != 'false') }} + run: npm run test --workspace=@getpaseo/highlight + + - name: Typecheck client examples + if: ${{ !cancelled() && steps.install.outcome == 'success' && (needs.changes.outputs.full != 'false' || needs.changes.outputs.sdk != 'false') }} + run: npm run typecheck:examples --workspace=@getpaseo/client + typecheck: name: typecheck needs: changes @@ -114,6 +149,9 @@ jobs: - name: Install dependencies run: node scripts/npm-retry.mjs ci + - name: Verify dependency patch recovery + run: node --test scripts/postinstall-patches.test.mjs + - name: Build server stack run: npm run build:server @@ -143,43 +181,56 @@ jobs: needs: changes if: ${{ !cancelled() && (needs.changes.outputs.full != 'false' || needs.changes.outputs.server != 'false' || needs.changes.outputs.hub != 'false') }} runs-on: ubuntu-latest - steps: &server_test_steps - - uses: actions/checkout@v4 + steps: + - &server_capacity + name: Log runner capacity + run: | + node -e "const os = require('node:os'); console.log(JSON.stringify({cpus: os.cpus().length, model: os.cpus()[0].model, ramGiB: os.totalmem() / 2 ** 30}))" + + - &server_checkout + uses: actions/checkout@v4 with: fetch-depth: 0 - - uses: actions/setup-node@v4 + - &server_node + uses: actions/setup-node@v4 with: node-version: "22" cache: "npm" - - name: Fetch origin/main (worktree tests) + - &server_fetch + name: Fetch origin/main (worktree tests) if: ${{ needs.changes.outputs.full != 'false' || needs.changes.outputs.server != 'false' }} run: git fetch --no-tags origin main:refs/remotes/origin/main - - name: Install dependencies + - &server_install + name: Install dependencies run: node scripts/npm-retry.mjs ci - - name: Install agent CLIs for provider tests + - &server_agent_clis + name: Install agent CLIs for provider tests if: ${{ needs.changes.outputs.full != 'false' || needs.changes.outputs.server != 'false' }} run: node scripts/npm-retry.mjs install -g @anthropic-ai/claude-code opencode-ai - - name: Build server dependencies + - &server_build + name: Build server dependencies run: npm run build:server-deps - name: Run server tests if: ${{ needs.changes.outputs.full != 'false' || needs.changes.outputs.server != 'false' }} run: npm run test --workspace=@getpaseo/server - env: + env: &server_test_env CLAUDE_CODE_OAUTH_TOKEN: ${{ secrets.CLAUDE_CODE_OAUTH_TOKEN }} OPENAI_API_KEY: ${{ secrets.OPENAI_API_KEY }} OPENROUTER_API_KEY: ${{ secrets.OPENROUTER_API_KEY }} - - name: Run built-in plugin tests + - &server_plugin_tests + name: Run built-in plugin tests if: ${{ needs.changes.outputs.full != 'false' || needs.changes.outputs.server != 'false' }} run: npm run test --workspace=@getpaseo/builtin-plugins - - name: Run Hub CLI/daemon contract + - &server_hub_contract + name: Run Hub CLI/daemon contract if: ${{ needs.changes.outputs.full == 'false' && needs.changes.outputs.server == 'false' && needs.changes.outputs.hub != 'false' }} run: npm run test:hub-cli-contract --workspace=@getpaseo/server @@ -188,7 +239,41 @@ jobs: needs: changes if: ${{ !cancelled() && (needs.changes.outputs.full != 'false' || needs.changes.outputs.server != 'false' || needs.changes.outputs.hub != 'false') }} runs-on: windows-latest - steps: *server_test_steps + steps: + - *server_capacity + - *server_checkout + - *server_node + - *server_fetch + - *server_install + - *server_agent_clis + - *server_build + + - name: Run server unit tests + if: ${{ needs.changes.outputs.full != 'false' || needs.changes.outputs.server != 'false' }} + run: npm run test:unit --workspace=@getpaseo/server + env: *server_test_env + + - *server_plugin_tests + - *server_hub_contract + + # Keep the serial integration chain off the Windows unit critical path. + server-integration-windows: + name: server-integration (windows-latest) + needs: changes + if: ${{ !cancelled() && (needs.changes.outputs.full != 'false' || needs.changes.outputs.server != 'false') }} + runs-on: windows-latest + steps: + - *server_capacity + - *server_checkout + - *server_node + - *server_fetch + - *server_install + - *server_agent_clis + - *server_build + + - name: Run server integration tests + run: npm run test:integration --workspace=@getpaseo/server + env: *server_test_env # native-recursive.ts serves darwin and win32, but windows-latest above is the only # runner that exercises it. macOS — the platform the reported watcher bug was on — @@ -332,52 +417,19 @@ jobs: - name: Run app unit tests run: npm run test --workspace=@getpaseo/app - sdk-tests: - name: sdk-tests - needs: changes - if: ${{ !cancelled() && (needs.changes.outputs.full != 'false' || needs.changes.outputs.sdk != 'false') }} - runs-on: ubuntu-latest - steps: - - uses: actions/checkout@v4 - - - uses: actions/setup-node@v4 - with: - node-version: "22" - cache: "npm" - - - name: Install dependencies - run: node scripts/npm-retry.mjs ci - - - name: Build client dependencies - run: npm run build:relay && npm run build:client - - - name: Build plugin SDK - run: npm run build:plugin - - - name: Run plugin SDK tests - run: npm run test --workspace=@getpaseo/plugin - - - name: Run protocol tests - run: npm run test --workspace=@getpaseo/protocol - - - name: Run client tests - run: npm run test --workspace=@getpaseo/client - - - name: Run highlight tests - run: npm run test --workspace=@getpaseo/highlight - - - name: Typecheck client examples - run: npm run typecheck:examples --workspace=@getpaseo/client - playwright-1: - name: playwright (shard 1/4) + name: playwright (shard 1/8) needs: changes if: ${{ !cancelled() && (needs.changes.outputs.full != 'false' || needs.changes.outputs.browser != 'false') }} runs-on: ubuntu-latest env: - PLAYWRIGHT_SHARD: "1/4" + PLAYWRIGHT_SHARD: "1/8" PLAYWRIGHT_ARTIFACT: "1" steps: &playwright_test_steps + - name: Log runner capacity + run: | + node -e "const os = require('node:os'); console.log(JSON.stringify({cpus: os.cpus().length, model: os.cpus()[0].model, ramGiB: os.totalmem() / 2 ** 30}))" + - uses: actions/checkout@v4 - uses: actions/setup-node@v4 @@ -405,9 +457,11 @@ jobs: run: npm run test:e2e --workspace=@getpaseo/app -- --shard=${{ env.PLAYWRIGHT_SHARD }} env: OPENAI_API_KEY: ${{ secrets.OPENAI_API_KEY }} - # Weight file groups by observed duration; raw test counts overload - # early agent/Changes specs. Required check names remain unchanged. - PWTEST_SHARD_WEIGHTS: "111:172:137:160" + E2E_WORKERS: "2" + # File groups are weighted by observed reporter durations. + # Share of the test list per shard, rebalanced from the Playwright step + # minutes of five eight-shard runs so the slowest and fastest shards meet. + PWTEST_SHARD_WEIGHTS: "85:94:117:128:91:103:127:85" - name: Upload test artifacts uses: actions/upload-artifact@v4 @@ -420,56 +474,74 @@ jobs: retention-days: 7 playwright-2: - name: playwright (shard 2/4) + name: playwright (shard 2/8) needs: changes if: ${{ !cancelled() && (needs.changes.outputs.full != 'false' || needs.changes.outputs.browser != 'false') }} runs-on: ubuntu-latest env: - PLAYWRIGHT_SHARD: "2/4" + PLAYWRIGHT_SHARD: "2/8" PLAYWRIGHT_ARTIFACT: "2" steps: *playwright_test_steps playwright-3: - name: playwright (shard 3/4) + name: playwright (shard 3/8) needs: changes if: ${{ !cancelled() && (needs.changes.outputs.full != 'false' || needs.changes.outputs.browser != 'false') }} runs-on: ubuntu-latest env: - PLAYWRIGHT_SHARD: "3/4" + PLAYWRIGHT_SHARD: "3/8" PLAYWRIGHT_ARTIFACT: "3" steps: *playwright_test_steps playwright-4: - name: playwright (shard 4/4) + name: playwright (shard 4/8) needs: changes if: ${{ !cancelled() && (needs.changes.outputs.full != 'false' || needs.changes.outputs.browser != 'false') }} runs-on: ubuntu-latest env: - PLAYWRIGHT_SHARD: "4/4" + PLAYWRIGHT_SHARD: "4/8" PLAYWRIGHT_ARTIFACT: "4" steps: *playwright_test_steps - relay-tests: - name: relay-tests + playwright-5: + name: playwright (shard 5/8) needs: changes - if: ${{ !cancelled() && (needs.changes.outputs.full != 'false' || needs.changes.outputs.relay != 'false') }} + if: ${{ !cancelled() && (needs.changes.outputs.full != 'false' || needs.changes.outputs.browser != 'false') }} runs-on: ubuntu-latest - steps: - - uses: actions/checkout@v4 + env: + PLAYWRIGHT_SHARD: "5/8" + PLAYWRIGHT_ARTIFACT: "5" + steps: *playwright_test_steps - - uses: actions/setup-node@v4 - with: - node-version: "22" - cache: "npm" + playwright-6: + name: playwright (shard 6/8) + needs: changes + if: ${{ !cancelled() && (needs.changes.outputs.full != 'false' || needs.changes.outputs.browser != 'false') }} + runs-on: ubuntu-latest + env: + PLAYWRIGHT_SHARD: "6/8" + PLAYWRIGHT_ARTIFACT: "6" + steps: *playwright_test_steps - - name: Install dependencies - run: node scripts/npm-retry.mjs ci + playwright-7: + name: playwright (shard 7/8) + needs: changes + if: ${{ !cancelled() && (needs.changes.outputs.full != 'false' || needs.changes.outputs.browser != 'false') }} + runs-on: ubuntu-latest + env: + PLAYWRIGHT_SHARD: "7/8" + PLAYWRIGHT_ARTIFACT: "7" + steps: *playwright_test_steps - - name: Build relay - run: npm run build:relay - - - name: Run relay tests - run: npm run test --workspace=@getpaseo/relay + playwright-8: + name: playwright (shard 8/8) + needs: changes + if: ${{ !cancelled() && (needs.changes.outputs.full != 'false' || needs.changes.outputs.browser != 'false') }} + runs-on: ubuntu-latest + env: + PLAYWRIGHT_SHARD: "8/8" + PLAYWRIGHT_ARTIFACT: "8" + steps: *playwright_test_steps cli-tests-1: name: cli-tests (shard 1/3) diff --git a/.oxlintrc.json b/.oxlintrc.json index 4582602a97..f5078649c9 100644 --- a/.oxlintrc.json +++ b/.oxlintrc.json @@ -5,6 +5,7 @@ }, "ignorePatterns": [".dev/**"], "plugins": ["react", "react-perf", "unicorn", "typescript", "oxc", "import", "promise"], + "jsPlugins": ["./scripts/oxlint/paseo-plugin.mjs"], "categories": { "correctness": "error", "suspicious": "error", @@ -356,6 +357,117 @@ "no-restricted-imports": "off" } }, + { + "files": ["packages/app/src/**/*.{ts,tsx}"], + "rules": { + "paseo/no-raw-pressable": "error" + } + }, + // Press feedback is owned by the primitives in components/ui. Raw pressable burn-down: + // 94 files. They may only leave this list. + { + "files": [ + "packages/app/src/components/ui/**/*.{ts,tsx}", + "packages/app/src/**/*.{test,spec}.{ts,tsx}", + "packages/app/src/agent-profiles/settings/agent-profile-appearance-field.tsx", + "packages/app/src/agent-skills/selection-sheet.tsx", + "packages/app/src/agent-stream/chat-outline/rail.web.tsx", + "packages/app/src/agent-stream/view.tsx", + "packages/app/src/app/pair-scan.tsx", + "packages/app/src/changelog/internal/changelog-sheet.tsx", + "packages/app/src/command-center/command-center.tsx", + "packages/app/src/components/adaptive-modal-sheet.tsx", + "packages/app/src/components/add-host-method-modal.tsx", + "packages/app/src/components/add-host-modal.tsx", + "packages/app/src/components/add-project-flow.tsx", + "packages/app/src/components/add-remote-ssh-host-modal.tsx", + "packages/app/src/components/agent-list.tsx", + "packages/app/src/components/app-diagnostic-sheet.tsx", + "packages/app/src/components/attachment-lightbox.tsx", + "packages/app/src/components/attachment-pill.tsx", + "packages/app/src/components/combined-model-selector.tsx", + "packages/app/src/components/compact-explorer-sidebar.tsx", + "packages/app/src/components/context-window-meter.tsx", + "packages/app/src/components/desktop/window-controls.tsx", + "packages/app/src/components/dictation-controls.tsx", + "packages/app/src/components/download-toast.tsx", + "packages/app/src/components/file-explorer-pane.tsx", + "packages/app/src/components/headers/back-header.tsx", + "packages/app/src/components/highlighted-code-block.tsx", + "packages/app/src/components/hosts/host-filter.tsx", + "packages/app/src/components/hosts/host-picker.tsx", + "packages/app/src/components/import-session-sheet.tsx", + "packages/app/src/components/left-sidebar.tsx", + "packages/app/src/components/markdown/fence/mermaid/host.native.tsx", + "packages/app/src/components/markdown/fence/mermaid/host.web.tsx", + "packages/app/src/components/message.tsx", + "packages/app/src/components/model-browser.tsx", + "packages/app/src/components/plan-card.tsx", + "packages/app/src/components/provider-diagnostic-sheet.tsx", + "packages/app/src/components/question-form-card.tsx", + "packages/app/src/components/realtime-voice-overlay.tsx", + "packages/app/src/components/schedules/schedule-row.tsx", + "packages/app/src/components/settings/collapsible-row.tsx", + "packages/app/src/components/settings/headings/settings-info-tip.tsx", + "packages/app/src/components/sidebar-callout.tsx", + "packages/app/src/components/sidebar-resize-handle.tsx", + "packages/app/src/components/sidebar-workspace-list.tsx", + "packages/app/src/components/sidebar/sidebar-group-toggle-row.tsx", + "packages/app/src/components/sidebar/sidebar-header-row.tsx", + "packages/app/src/components/sidebar/sidebar-section-header.tsx", + "packages/app/src/components/sidebar/sidebar-status-list.tsx", + "packages/app/src/components/sidebar/workspace-meta-row/index.tsx", + "packages/app/src/components/terminal-copy-paste-actions.tsx", + "packages/app/src/components/terminal-emulator-native-grid.native.tsx", + "packages/app/src/components/terminal-pane.tsx", + "packages/app/src/components/toast-host.tsx", + "packages/app/src/components/tool-call-sheet.tsx", + "packages/app/src/components/welcome-screen.tsx", + "packages/app/src/components/workspace-hover-card.tsx", + "packages/app/src/components/zoomable-viewport/toolbar.tsx", + "packages/app/src/composer/agent-controls/index.tsx", + "packages/app/src/composer/diff-stat-pill.tsx", + "packages/app/src/composer/dock/internal/background.native.tsx", + "packages/app/src/composer/draft/import-pill.tsx", + "packages/app/src/composer/index.tsx", + "packages/app/src/composer/tracks.tsx", + "packages/app/src/desktop/browser/pane/index.electron.tsx", + "packages/app/src/git/actions-split-button.tsx", + "packages/app/src/git/commits-section/commit-row.tsx", + "packages/app/src/git/commits-section/commits-section.tsx", + "packages/app/src/git/diff-pane.tsx", + "packages/app/src/git/forges/gitlab.view.tsx", + "packages/app/src/git/pull-request-panel/checks-section.tsx", + "packages/app/src/git/pull-request-panel/pane.tsx", + "packages/app/src/git/pull-request-panel/section-kit.tsx", + "packages/app/src/hosts/host-chooser.tsx", + "packages/app/src/mobile-panels/presentation.tsx", + "packages/app/src/panels/new-tab-panel.tsx", + "packages/app/src/panels/setup-panel.tsx", + "packages/app/src/plugins/buttons/view.tsx", + "packages/app/src/review/surface.tsx", + "packages/app/src/screens/open-project-screen.tsx", + "packages/app/src/screens/project-settings-screen.tsx", + "packages/app/src/screens/projects-screen.tsx", + "packages/app/src/screens/settings-screen.tsx", + "packages/app/src/screens/settings/host-appearance-section.tsx", + "packages/app/src/screens/settings/host-page.tsx", + "packages/app/src/screens/settings/providers-section.tsx", + "packages/app/src/screens/workspace/compact-workspace-header/tab-switcher.tsx", + "packages/app/src/screens/workspace/scripts/workspace-scripts-button.tsx", + "packages/app/src/screens/workspace/workspace-desktop-tabs-row.tsx", + "packages/app/src/screens/workspace/workspace-tab-presentation.tsx", + "packages/app/src/tool-calls/detail-level/overview/sheet.tsx", + "packages/app/src/usage/sidebar-item.tsx", + "packages/app/src/usage/window-bar.tsx", + "packages/app/src/workspace-labels/manager-modal.tsx", + "packages/app/src/workspace-labels/swatch.tsx", + "packages/app/src/workspace/open-in-editor/button.tsx" + ], + "rules": { + "paseo/no-raw-pressable": "off" + } + }, { "files": ["**/e2e/**/fixtures.ts"], "rules": { diff --git a/CHANGELOG.md b/CHANGELOG.md index 80dc5d17e4..af0f7904ba 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,8 +1,8 @@ # Changelog -## 0.12.0-beta.1 - 2026-10-16 +## 0.12.0 - 2026-10-19 -Background workspaces, a new Markdown renderer with selection across paragraphs on phones, a reworked phone layout, and close to 100 fixes. +Background workspaces, a new Markdown renderer with selection across paragraphs on phones, a reworked phone layout, and more than 120 fixes. **Before upgrading:** `paseo run --background` is deprecated in favor of `--no-wait`, and `paseo permit allow` and `deny` now exit non-zero when the daemon doesn't confirm within 15 seconds @@ -27,8 +27,15 @@ Background workspaces, a new Markdown renderer with selection across paragraphs - Changed phones to open files and subagents in a closable sheet, with Open as tab for subagents ([#6827](https://github.com/getpaseo/paseo/pull/6827), [#6885](https://github.com/getpaseo/paseo/pull/6885), [#6958](https://github.com/getpaseo/paseo/pull/6958)) - Changed diff comments on phones to open in a sheet instead of an editor inside the code ([#6455](https://github.com/getpaseo/paseo/pull/6455)) - Changed Settings on phones to large tiles grouped into App and Host ([#7129](https://github.com/getpaseo/paseo/pull/7129)) -- Reduced rendering work in long chats while a reply streams ([#7052](https://github.com/getpaseo/paseo/pull/7052) by [@colonelpanic8](https://github.com/colonelpanic8)) +- Changed Command Center to rank workspaces and agents by match and then recency, and to show timestamps, project icons, and highlighted matches ([#7277](https://github.com/getpaseo/paseo/pull/7277)) +- Added each Paseo subagent's model, thinking, mode, and context under its title in the subagents list ([#7290](https://github.com/getpaseo/paseo/pull/7290)) +- Made subagent rows in the Subagents panel taller on phones, and gave their archive and detach buttons the standard press highlight ([#7364](https://github.com/getpaseo/paseo/pull/7364)) +- Changed Paseo tool calls in chats to lead with the action and its context, such as Send message · the first line of the prompt ([#7283](https://github.com/getpaseo/paseo/pull/7283)) +- Changed the New workspace form on phones to full-width fields, with Import session in the header ([#7239](https://github.com/getpaseo/paseo/pull/7239)) +- Reduced rendering work in long chats while a reply streams ([#7052](https://github.com/getpaseo/paseo/pull/7052) by [@colonelpanic8](https://github.com/colonelpanic8), [#7342](https://github.com/getpaseo/paseo/pull/7342)) - Made reopening the sidebar about 45% faster ([#7157](https://github.com/getpaseo/paseo/pull/7157)) +- Made projects and workspaces load faster after the app reconnects ([#7242](https://github.com/getpaseo/paseo/pull/7242)) +- Changed messages one agent sends another through the CLI or MCP to steer its running turn instead of interrupting it ([#5164](https://github.com/getpaseo/paseo/pull/5164) by [@derwells](https://github.com/derwells)) - Changed Gitea and Forgejo fork PR checkouts to include the fork owner in the branch name, such as `bob/patch-1` ([#6829](https://github.com/getpaseo/paseo/pull/6829) by [@alexanderadam](https://github.com/alexanderadam)) ### Plugins @@ -37,6 +44,10 @@ Background workspaces, a new Markdown renderer with selection across paragraphs - Fixed `providers.waitForReady` throwing in plugins on the mobile app ([#6760](https://github.com/getpaseo/paseo/pull/6760) by [@GeorgeR](https://github.com/GeorgeR)) - Fixed the chat outline not jumping to prompts rendered by a timeline plugin ([#6690](https://github.com/getpaseo/paseo/pull/6690) by [@lukeRRD](https://github.com/lukeRRD)) - Fixed Escape stopping the running agent instead of first closing an open plugin preview ([#7110](https://github.com/getpaseo/paseo/pull/7110) by [@RRD-dev](https://github.com/RRD-dev), [@luoph](https://github.com/luoph)) +- Fixed `paseo plugin reload` failing with a 60-second timeout while the reload was still running ([#6306](https://github.com/getpaseo/paseo/pull/6306) by [@Mtuchel](https://github.com/Mtuchel)) +- Fixed follow-ups sent while a plugin ACP agent runs failing with "Provider does not support prompt.steer" ([#7270](https://github.com/getpaseo/paseo/pull/7270) by [@simonepri](https://github.com/simonepri)) +- Fixed Find showing no matches for prompt text drawn by a timeline plugin ([#7253](https://github.com/getpaseo/paseo/pull/7253) by [@a-grasso](https://github.com/a-grasso)) +- Fixed late-loading composer plugin pills covering Copy and Fork after reopening a chat ([#7341](https://github.com/getpaseo/paseo/pull/7341) by [@sholiday](https://github.com/sholiday)) ### Fixed @@ -50,16 +61,29 @@ Background workspaces, a new Markdown renderer with selection across paragraphs - Fixed an incomplete font name in Appearance breaking the app's styling ([#6695](https://github.com/getpaseo/paseo/pull/6695)) - Fixed the Linux desktop window never appearing when the hidden window renders no frames ([#6726](https://github.com/getpaseo/paseo/pull/6726) by [@EhEo](https://github.com/EhEo)) - Fixed opening another agent or workspace stalling while a different agent on the same host is streaming ([#7074](https://github.com/getpaseo/paseo/pull/7074) by [@colonelpanic8](https://github.com/colonelpanic8)) +- Fixed the project's New workspace button choosing the first host instead of the active workspace's host ([#7308](https://github.com/getpaseo/paseo/pull/7308)) +- Fixed the composer staying focused after switching tabs with keyboard shortcuts in touch browsers ([#7352](https://github.com/getpaseo/paseo/pull/7352)) +- Fixed the daemon running out of memory when several directory searches overlap on a large folder tree ([#7265](https://github.com/getpaseo/paseo/pull/7265)) +- Fixed dragging the Explorer edge stuttering with several panes open ([#7284](https://github.com/getpaseo/paseo/pull/7284) by [@colonelpanic8](https://github.com/colonelpanic8)) - Fixed agent creation showing an error and a retry draft when the provider rejected the first prompt ([#6379](https://github.com/getpaseo/paseo/pull/6379)) +- Fixed new agent drafts staying on "Loading…" when the host is disconnected; they now say "Host is not connected" and keep your draft ([#7303](https://github.com/getpaseo/paseo/pull/7303) by [@colonelpanic8](https://github.com/colonelpanic8)) +- Fixed reloading a chat during a streaming reply showing a frozen copy above the live one and dropping the ending ([#7256](https://github.com/getpaseo/paseo/pull/7256)) +- Fixed question cards spinning forever when an answer fails to send; they now show the error and keep your answers ([#7098](https://github.com/getpaseo/paseo/pull/7098) by [@xzthemeofsss](https://github.com/xzthemeofsss)) - Fixed parent agents missing the finish notification when a child finished its first turn very quickly ([#6008](https://github.com/getpaseo/paseo/pull/6008) by [@ahmet-izgi](https://github.com/ahmet-izgi)) - Fixed parent agents being told a child finished when its task was stopped or reloaded ([#6660](https://github.com/getpaseo/paseo/pull/6660) by [@Mar-garet](https://github.com/Mar-garet)) - Fixed Codex chats containing U+2028 or U+2029 failing to reopen on Node 24 ([#5999](https://github.com/getpaseo/paseo/pull/5999) by [@grahameger](https://github.com/grahameger), [@jtsang4](https://github.com/jtsang4), [@kotusenka](https://github.com/kotusenka)) +- Fixed resumed Codex goals appearing idle and refusing Stop after a continuation ([#7339](https://github.com/getpaseo/paseo/pull/7339) by [@hemaaanth](https://github.com/hemaaanth)) - Fixed Add Project directory search hanging the daemon on macOS when it entered `~/Library` ([#5789](https://github.com/getpaseo/paseo/pull/5789) by [@lardissone](https://github.com/lardissone)) - Fixed New workspace failing with "Invalid mode" when the saved mode isn't offered by the provider ([#5847](https://github.com/getpaseo/paseo/pull/5847) by [@mcowger](https://github.com/mcowger)) - Fixed answering multi-select OpenCode v2 questions failing with "Invalid answer" ([#6149](https://github.com/getpaseo/paseo/pull/6149) by [@gammons](https://github.com/gammons)) - Fixed browser screenshots failing the turn on OpenCode v2 agents ([#6330](https://github.com/getpaseo/paseo/pull/6330)) - Fixed OpenCode v2 agents receiving "HTTP 500" instead of the Paseo tool error ([#6519](https://github.com/getpaseo/paseo/pull/6519)) +- Fixed OpenCode agents receiving "HTTP 500" instead of a readable error when they call a Paseo tool with invalid arguments or an unknown name ([#7183](https://github.com/getpaseo/paseo/pull/7183)) - Fixed rewinding a Claude conversation failing with "Session not found" when the provider sets `CLAUDE_CONFIG_DIR` ([#6325](https://github.com/getpaseo/paseo/pull/6325)) +- Fixed changing a running Claude agent's thinking level and then its mode killing its running command ([#7179](https://github.com/getpaseo/paseo/pull/7179)) +- Fixed Claude models that need a recent Claude Code being hidden when the provider command is a wrapper script ([#7209](https://github.com/getpaseo/paseo/pull/7209) by [@SulthanZahran1](https://github.com/SulthanZahran1)) +- Fixed background Claude subagent cards staying empty while the subagent works, including after the parent finishes ([#6242](https://github.com/getpaseo/paseo/pull/6242), [#7266](https://github.com/getpaseo/paseo/pull/7266)) +- Fixed Copilot staying in Plan mode and refusing edits after you select Allow All ([#7234](https://github.com/getpaseo/paseo/pull/7234)) - Fixed imported Claude Code sessions taking their first prompt as the name instead of their `/rename` title ([#6930](https://github.com/getpaseo/paseo/pull/6930) by [@platanus-kr](https://github.com/platanus-kr)) - Fixed a wrongly shaped answer to a Claude question reporting success and discarding the question ([#6936](https://github.com/getpaseo/paseo/pull/6936) by [@thomasvan](https://github.com/thomasvan)) - Fixed Cursor agents showing no plan usage in their context details ([#6353](https://github.com/getpaseo/paseo/pull/6353) by [@gengjiawen](https://github.com/gengjiawen)) @@ -80,15 +104,24 @@ Background workspaces, a new Markdown renderer with selection across paragraphs - Fixed a service newly added to `paseo.json` failing to start until the daemon restarted ([#6542](https://github.com/getpaseo/paseo/pull/6542)) - Fixed workspace service URLs returning 502 when the service listens only on IPv6 localhost ([#6753](https://github.com/getpaseo/paseo/pull/6753) by [@marcelocastrobarbosa](https://github.com/marcelocastrobarbosa)) - Fixed terminals that could not be closed when their command was missing or exited immediately ([#6792](https://github.com/getpaseo/paseo/pull/6792) by [@KiraPC](https://github.com/KiraPC)) -- Fixed CJK terminal text gaining spaces between characters after returning to a workspace ([#6452](https://github.com/getpaseo/paseo/pull/6452) by [@jasonhnd](https://github.com/jasonhnd), [@liujin0506](https://github.com/liujin0506), [@seob717](https://github.com/seob717)) +- Fixed MCP terminal key commands typing arrow and modifier key names instead of sending the keys ([#7343](https://github.com/getpaseo/paseo/pull/7343) by [@Aling33](https://github.com/Aling33)) +- Fixed CJK text gaining spaces between characters after returning to a workspace in the native terminal ([#6452](https://github.com/getpaseo/paseo/pull/6452) by [@jasonhnd](https://github.com/jasonhnd), [@liujin0506](https://github.com/liujin0506), [@seob717](https://github.com/seob717)) +- Fixed copying Korean text from the terminal on iOS and Android adding spaces between characters or dropping the first one ([#7254](https://github.com/getpaseo/paseo/pull/7254), [#7260](https://github.com/getpaseo/paseo/pull/7260) by [@helloimdevman](https://github.com/helloimdevman)) +- Fixed long-pressing a Korean word in the terminal on iOS and Android selecting only one character instead of the whole word ([#7353](https://github.com/getpaseo/paseo/pull/7353)) - Fixed the self-hosted web app failing to connect through a reverse proxy on port 80 or 443 ([#6638](https://github.com/getpaseo/paseo/pull/6638) by [@kiawin](https://github.com/kiawin)) +- Fixed the Hub connection never reconnecting after a silent network failure ([#7315](https://github.com/getpaseo/paseo/pull/7315)) +- Fixed remote connections failing on slow networks when another resolved address is unreachable ([#7336](https://github.com/getpaseo/paseo/pull/7336)) - Fixed assistant file links with spaces or non-ASCII characters failing with ENOENT ([#6520](https://github.com/getpaseo/paseo/pull/6520) by [@apple-ouyang](https://github.com/apple-ouyang), [@sunshinehomeyu-blip](https://github.com/sunshinehomeyu-blip)) - Fixed local images in agent replies failing to load when their path contains spaces or non-ASCII characters ([#6877](https://github.com/getpaseo/paseo/pull/6877)) - Fixed Markdown file previews not showing images referenced by relative paths ([#6750](https://github.com/getpaseo/paseo/pull/6750) by [@apple-ouyang](https://github.com/apple-ouyang)) +- Fixed folder links in chats and Markdown previews opening an error tab or doing nothing; they now open Files with the folder's contents visible ([#7205](https://github.com/getpaseo/paseo/pull/7205), [#7210](https://github.com/getpaseo/paseo/pull/7210), [#7229](https://github.com/getpaseo/paseo/pull/7229)) +- Fixed Markdown links to files such as `[Capture](capture.png)` doing nothing for some file types ([#7233](https://github.com/getpaseo/paseo/pull/7233)) - Fixed iOS sidebar rows staying highlighted and swallowing the next tap after a brief hold ([#7159](https://github.com/getpaseo/paseo/pull/7159) by [@kassamkhoja](https://github.com/kassamkhoja)) - Fixed Android chats scrolling when you long-press to select text ([#7131](https://github.com/getpaseo/paseo/pull/7131) by [@RRD-dev](https://github.com/RRD-dev), [@luoph](https://github.com/luoph)) - Fixed sidebar rows, footer buttons, and Settings items showing no feedback when tapped on touch devices ([#7150](https://github.com/getpaseo/paseo/pull/7150)) -- Fixed Page Up and Page Down not scrolling the chat after clicking a message ([#7033](https://github.com/getpaseo/paseo/pull/7033) by [@panta82](https://github.com/panta82)) +- Fixed home screen actions being cut off on short phone screens ([#7167](https://github.com/getpaseo/paseo/pull/7167)) +- Fixed Android dictation stopping with "Dictation was interrupted by another audio source" when another app plays audio ([#7200](https://github.com/getpaseo/paseo/pull/7200)) +- Fixed Page Up and Page Down not scrolling the chat after clicking a message or closing Find ([#7033](https://github.com/getpaseo/paseo/pull/7033), [#7263](https://github.com/getpaseo/paseo/pull/7263) by [@panta82](https://github.com/panta82)) - Fixed Add Project keyboard selection moving to directories scrolled out of view ([#7081](https://github.com/getpaseo/paseo/pull/7081) by [@superheher](https://github.com/superheher)) - Fixed Enter replacing an email address in the composer with a file mention ([#6471](https://github.com/getpaseo/paseo/pull/6471) by [@jasonhnd](https://github.com/jasonhnd)) - Fixed letter shortcuts not running with non-Latin keyboard layouts such as Russian ([#6755](https://github.com/getpaseo/paseo/pull/6755)) @@ -108,6 +141,7 @@ Background workspaces, a new Markdown renderer with selection across paragraphs - Fixed the Pi thinking level not updating when a Pi extension changes it ([#6741](https://github.com/getpaseo/paseo/pull/6741)) - Fixed Pi subagents from `@tintinweb/pi-subagents` staying running after their turn limit ([#6594](https://github.com/getpaseo/paseo/pull/6594) by [@Chen-DaYi](https://github.com/Chen-DaYi)) - Fixed manual `/compact` on OMP agents showing no progress and leaving the context meter stale ([#6106](https://github.com/getpaseo/paseo/pull/6106)) +- Fixed follow-ups to idle OMP agents staying queued instead of starting the agent ([#7169](https://github.com/getpaseo/paseo/pull/7169) by [@nhthung](https://github.com/nhthung)) - Fixed voice mode TTS rejecting model and voice names from OpenAI-compatible servers ([#6060](https://github.com/getpaseo/paseo/pull/6060) by [@khimaros](https://github.com/khimaros)) - Fixed the xhigh thinking option showing "Extra high" instead of its configured label ([#6005](https://github.com/getpaseo/paseo/pull/6005) by [@EliorFureraj](https://github.com/EliorFureraj)) - Fixed the Remove button going off screen for long custom model names in provider settings ([#6507](https://github.com/getpaseo/paseo/pull/6507)) @@ -132,7 +166,11 @@ Background workspaces, a new Markdown renderer with selection across paragraphs - Fixed Google Play listing Android devices without a camera as incompatible ([#6339](https://github.com/getpaseo/paseo/pull/6339)) - Fixed `nix build .#desktop` running out of memory on Macs with less than 15 GB of RAM ([#6537](https://github.com/getpaseo/paseo/pull/6537) by [@truelecter](https://github.com/truelecter)) - Fixed usage providers changing places after Refresh all ([#6947](https://github.com/getpaseo/paseo/pull/6947) by [@sleroq](https://github.com/sleroq)) +- Fixed usage cards losing their last values and showing "Updated" when a refresh fails ([#7246](https://github.com/getpaseo/paseo/pull/7246)) +- Fixed Usage merging distinct Cursor accounts into one card ([#7344](https://github.com/getpaseo/paseo/pull/7344)) - Fixed the OpenCode Go usage icon being nearly invisible on dark themes ([#6362](https://github.com/getpaseo/paseo/pull/6362) by [@az33zy](https://github.com/az33zy)) +- Fixed generic icons for Devin, Hermes, Kiro, and Antigravity in provider lists ([#7330](https://github.com/getpaseo/paseo/pull/7330) by [@OMEG-Lu](https://github.com/OMEG-Lu), [@kevenhu001-cyber](https://github.com/kevenhu001-cyber)) +- Fixed sidebar setup buttons overflowing the card with long translated labels ([#7312](https://github.com/getpaseo/paseo/pull/7312) by [@gentslava](https://github.com/gentslava)) ## 0.11.4 - 2026-10-15 diff --git a/docs/design.md b/docs/design.md index e21270c85d..ce45577b69 100644 --- a/docs/design.md +++ b/docs/design.md @@ -20,7 +20,7 @@ A semantic element used in three or more places is a primitive. One of a kind is Primitives live in `packages/app/src/components/ui/` and `packages/app/src/components/headers/`. Card and row layout live in `packages/app/src/styles/settings.ts`. Section structure lives in `packages/app/src/screens/settings/settings-section.tsx`. -A pressable styled to look like a button is wrong; the button is `", + ); + expect(findRenderedMatches(row, "needle").map((range) => range.toString())).toEqual([ + "needle", + "needle", + ]); + expect(findRenderedMatches(row, "Promptfind")).toEqual([]); + expect(findRenderedMatches(row, "find this needle")).toHaveLength(1); + expect(findMessageMatches(row.parentElement, "message-1", "needle")).toHaveLength(2); +}); + +it("leaves rows without the plugin marker limited to marked message text", () => { + const row = document.createElement("div"); + row.innerHTML = "
needle
"; + document.body.append(row); + expect(findRenderedMatches(row, "needle")).toEqual([]); +}); + +it("counts only drawn text in a plugin row, including an opened popover", () => { + const row = pluginRow( + '
visible needle
display needle
visibility needletransparent needle
popover needle
', + ); + expect(findRenderedMatches(row, "needle").map((range) => range.toString())).toEqual(["needle"]); + row.querySelector("[popover]")!.showPopover(); + expect(findRenderedMatches(row, "needle")).toHaveLength(2); +}); + +it("keeps text around nested plugin blocks in separate occurrences", () => { + const row = pluginRow("
alpha
details
beta
gamma
delta
"); + expect(findRenderedMatches(row, "alpha beta")).toEqual([]); + expect(findRenderedMatches(row, "gamma delta")).toEqual([]); + expect(findRenderedMatches(row, "details").map((range) => range.toString())).toEqual(["details"]); + expect(findRenderedMatches(row, "beta").map((range) => range.toString())).toEqual(["beta"]); +}); diff --git a/packages/app/src/agent-stream/chat-find/ranges.web.ts b/packages/app/src/agent-stream/chat-find/ranges.web.ts index ea2e901c2d..13da1034a2 100644 --- a/packages/app/src/agent-stream/chat-find/ranges.web.ts +++ b/packages/app/src/agent-stream/chat-find/ranges.web.ts @@ -21,28 +21,55 @@ export function findMessageMatches( return findMessageRows(root, messageId).flatMap((row) => findRenderedMatches(row, query)); } +function renderedTextGroups(row: HTMLElement): Text[][] { + const groups: Text[][] = []; + // A plugin renderer owns the DOM of the message it replaced and sets no markers, so the + // whole row is searched and each div (a React Native View or Text) bounds a match. + const pluginRow = row.dataset.pluginRow === "true"; + const blocks = pluginRow ? `${BLOCKS},div` : BLOCKS; + const contents = pluginRow + ? [row] + : row.querySelectorAll('[data-message-text="true"]'); + for (const content of contents) { + let group: { block: Element; texts: Text[] } | undefined; + const walker = document.createTreeWalker( + content, + NodeFilter.SHOW_ELEMENT | NodeFilter.SHOW_TEXT, + ); + let node: Node | null; + while ((node = walker.nextNode())) { + if (node instanceof Element) { + // Even an empty nested block separates the text before and after it. + if (node.matches(blocks)) group = undefined; + continue; + } + if (!(node instanceof Text) || node.parentElement?.closest(IGNORED)) continue; + if ( + pluginRow && + !node.parentElement?.checkVisibility({ opacityProperty: true, visibilityProperty: true }) + ) + continue; + const block = node.parentElement?.closest(blocks) ?? content; + if (group?.block !== block) { + group = { block, texts: [] }; + groups.push(group.texts); + } + group.texts.push(node); + } + } + return groups; +} + /** Local offsets belong to the DOM that supplied the text, never to a host parser. */ export function findRenderedMatches(row: HTMLElement, query: string): Range[] { if (!query.trim()) return []; - const groups = new Map(); - for (const content of row.querySelectorAll('[data-message-text="true"]')) { - const walker = document.createTreeWalker(content, NodeFilter.SHOW_TEXT); - let node: Node | null; - while ((node = walker.nextNode())) { - if (!(node instanceof Text) || node.parentElement?.closest(IGNORED)) continue; - const block = node.parentElement?.closest(BLOCKS) ?? content; - const texts = groups.get(block) ?? []; - texts.push(node); - groups.set(block, texts); - } - } const pattern = query .trim() .split(/\s+/) .map((part) => part.replace(/[.*+?^${}()|[\]\\]/g, "\\$&")) .join("\\s+"); const ranges: Range[] = []; - for (const texts of groups.values()) { + for (const texts of renderedTextGroups(row)) { const points = texts.map((node) => ({ node, start: 0, end: 0 })); let text = ""; for (const point of points) { diff --git a/packages/app/src/agent-stream/native-scroll-animation.test.ts b/packages/app/src/agent-stream/native-scroll-animation.test.ts new file mode 100644 index 0000000000..947b8c3d1d --- /dev/null +++ b/packages/app/src/agent-stream/native-scroll-animation.test.ts @@ -0,0 +1,34 @@ +import { describe, expect, it } from "vitest"; +import { shouldAnimateNativeScrollToBottom } from "./native-scroll-animation"; + +describe("native scroll-to-bottom animation", () => { + it("jumps across unmounted history instead of animating through blank rows", () => { + expect( + shouldAnimateNativeScrollToBottom({ offsetY: 60_000, viewportHeight: 600, windowSize: 10 }), + ).toBe(false); + }); + + it("keeps near-bottom movement eligible for animation", () => { + expect( + shouldAnimateNativeScrollToBottom({ offsetY: 300, viewportHeight: 600, windowSize: 10 }), + ).toBe(true); + }); + + it("bounds travel by the bottom-side overscan, not the whole window", () => { + expect( + shouldAnimateNativeScrollToBottom({ offsetY: 2700, viewportHeight: 600, windowSize: 10 }), + ).toBe(true); + expect( + shouldAnimateNativeScrollToBottom({ offsetY: 2701, viewportHeight: 600, windowSize: 10 }), + ).toBe(false); + expect( + shouldAnimateNativeScrollToBottom({ offsetY: 1500, viewportHeight: 600, windowSize: 5 }), + ).toBe(false); + }); + + it("does not animate before the viewport has been measured", () => { + expect( + shouldAnimateNativeScrollToBottom({ offsetY: 0, viewportHeight: 0, windowSize: 10 }), + ).toBe(false); + }); +}); diff --git a/packages/app/src/agent-stream/native-scroll-animation.ts b/packages/app/src/agent-stream/native-scroll-animation.ts new file mode 100644 index 0000000000..72bc39108c --- /dev/null +++ b/packages/app/src/agent-stream/native-scroll-animation.ts @@ -0,0 +1,10 @@ +export function shouldAnimateNativeScrollToBottom(input: { + offsetY: number; + viewportHeight: number; + windowSize: number; +}): boolean { + // VirtualizedList splits the extra window around the viewport. An animated + // jump farther than the bottom-side overscan crosses unmounted history. + const bottomOverscanHeight = ((input.windowSize - 1) / 2) * input.viewportHeight; + return input.viewportHeight > 0 && input.offsetY <= bottomOverscanHeight; +} diff --git a/packages/app/src/agent-stream/strategy-native.tsx b/packages/app/src/agent-stream/strategy-native.tsx index 66409f23e1..e7568edfe8 100644 --- a/packages/app/src/agent-stream/strategy-native.tsx +++ b/packages/app/src/agent-stream/strategy-native.tsx @@ -23,6 +23,7 @@ import type { StreamItem } from "@/types/stream"; import type { Theme } from "@/styles/theme"; import { useStableEvent } from "@/hooks/use-stable-event"; import { useKeyboardStreamInset } from "@/keyboard/shift"; +import { shouldAnimateNativeScrollToBottom } from "./native-scroll-animation"; import { useRevisedHistoryRows } from "./history-row-revision"; import { useBottomAnchorController } from "./bottom-anchor-controller"; import { useScrollKeyboardDismiss } from "./scroll-keyboard-dismiss/use-scroll-keyboard-dismiss"; @@ -64,6 +65,7 @@ const historyStartSlotStyle: ViewStyle = { flexShrink: 0, }; const HISTORY_START_SETTLE_FRAMES = 2; +const NATIVE_STREAM_WINDOW_SIZE = 10; function keyExtractor(item: { id: string }): string { return item.id; @@ -238,7 +240,13 @@ function NativeStreamViewport(props: StreamRenderInput & { strategy: StreamStrat programmaticScrollEventBudgetRef.current = 3; flatListRef.current?.scrollToOffset({ offset: 0, - animated, + animated: + animated && + shouldAnimateNativeScrollToBottom({ + offsetY: scrollOffsetYRef.current, + viewportHeight: streamViewportMetricsRef.current.viewportHeight, + windowSize: NATIVE_STREAM_WINDOW_SIZE, + }), }); scrollOffsetYRef.current = 0; streamViewportMetricsRef.current = { @@ -591,11 +599,11 @@ function NativeStreamViewport(props: StreamRenderInput & { strategy: StreamStrat scrollEventThrottle={16} onContentSizeChange={handleContentSizeChange} maintainVisibleContentPosition={maintainVisibleContentPosition} - // A history row can contain an entire long reply. Keep synchronous native - // Markdown measurement bounded while FlatList fills the surrounding window. + // Tall Markdown rows exhaust a shallow window during flings. Keep the initial + // render small, then refill a deeper window in batches large enough to keep up. initialNumToRender={2} - maxToRenderPerBatch={2} - windowSize={5} + maxToRenderPerBatch={10} + windowSize={NATIVE_STREAM_WINDOW_SIZE} removeClippedSubviews={false} scrollEnabled={scrollEnabled} showsVerticalScrollIndicator diff --git a/packages/app/src/agent-stream/strategy-web.tsx b/packages/app/src/agent-stream/strategy-web.tsx index 97490c2a17..e57fc98e48 100644 --- a/packages/app/src/agent-stream/strategy-web.tsx +++ b/packages/app/src/agent-stream/strategy-web.tsx @@ -1162,6 +1162,7 @@ function WebStreamViewport(props: StreamRenderInput & { isMobileBreakpoint: bool useEffect(() => { const handle: StreamViewportHandle = { + focus: () => scrollContainerRef.current?.focus({ preventScroll: true }), scrollToBottom: () => { setFollowOutput(true); cancelPendingStickToBottom(); @@ -1250,6 +1251,7 @@ function WebStreamViewport(props: StreamRenderInput & { isMobileBreakpoint: bool key={item.id} data-history-row-id={item.id} data-message-id={getStreamItemMessageId(item)} + data-plugin-row={item.kind === "plugin" ? "true" : undefined} style={streamRowStyle} > diff --git a/packages/app/src/agent-stream/strategy.ts b/packages/app/src/agent-stream/strategy.ts index 5f43f8f6b1..7604b48cdd 100644 --- a/packages/app/src/agent-stream/strategy.ts +++ b/packages/app/src/agent-stream/strategy.ts @@ -51,6 +51,8 @@ export interface ScrollToMessageOccurrence { } export interface StreamViewportHandle { + /** Give keyboard navigation back to the scrolling surface on web. */ + focus?: () => void; scrollToBottom: (reason?: BottomAnchorLocalRequest["reason"]) => void; prepareForViewportChange: () => void; scrollToMessage?: (messageId: string, occurrence?: ScrollToMessageOccurrence) => void; diff --git a/packages/app/src/agent-stream/view.tsx b/packages/app/src/agent-stream/view.tsx index c9b44ed679..da2fd59d36 100644 --- a/packages/app/src/agent-stream/view.tsx +++ b/packages/app/src/agent-stream/view.tsx @@ -771,6 +771,7 @@ const AgentStreamViewComponent = forwardRef ); }, - [context.cwd, setInlineDetailsExpanded, handleToolCallOpenFile], + [context.cwd, resolvedServerId, setInlineDetailsExpanded, handleToolCallOpenFile], ); // Read through a stable event so live group updates do not change the renderer identity @@ -1251,6 +1252,12 @@ function agentStreamViewPropsEqual( if (left.isAuthoritativeHistoryReady !== right.isAuthoritativeHistoryReady) { reasons.push("isAuthoritativeHistoryReady"); } + if (left.bottomOverlayTailClearance !== right.bottomOverlayTailClearance) { + reasons.push("bottomOverlayTailClearance"); + } + if (left.bottomOverlayControlClearance !== right.bottomOverlayControlClearance) { + reasons.push("bottomOverlayControlClearance"); + } if (left.toast !== right.toast) reasons.push("toast"); if (left.onOpenWorkspaceFile !== right.onOpenWorkspaceFile) reasons.push("onOpenWorkspaceFile"); if (left.readOnly !== right.readOnly) reasons.push("readOnly"); diff --git a/packages/app/src/assets/acp-provider-icons.ts b/packages/app/src/assets/acp-provider-icons.ts index cebb4ca76d..703473e6be 100644 --- a/packages/app/src/assets/acp-provider-icons.ts +++ b/packages/app/src/assets/acp-provider-icons.ts @@ -53,9 +53,10 @@ export const ACP_PROVIDER_ICON_SVGS = { junie: '\n \n \n \n\n', kilo: '\n \n\n', + kiro: ' ', kimi: '\n \n\n', "minimax-code": - '\n \n\n', + '\n \n\n', "minion-code": '\n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n\n', "mistral-vibe": @@ -74,7 +75,11 @@ export const ACP_PROVIDER_ICON_SVGS = { stakpak: '\n \n\n', traecli: - '\n \n\n', + '\n \n\n', vtcode: '\n \n VT\n\n', + devin: + '\n \n\n', + hermes: + '\n \n\n', } as const; diff --git a/packages/app/src/assets/acp-provider-icons/devin.svg b/packages/app/src/assets/acp-provider-icons/devin.svg new file mode 100644 index 0000000000..e0f58c6513 --- /dev/null +++ b/packages/app/src/assets/acp-provider-icons/devin.svg @@ -0,0 +1,3 @@ + + + diff --git a/packages/app/src/assets/acp-provider-icons/grok.svg b/packages/app/src/assets/acp-provider-icons/grok.svg new file mode 100644 index 0000000000..35db840319 --- /dev/null +++ b/packages/app/src/assets/acp-provider-icons/grok.svg @@ -0,0 +1,4 @@ + + + + diff --git a/packages/app/src/assets/acp-provider-icons/hermes.svg b/packages/app/src/assets/acp-provider-icons/hermes.svg new file mode 100644 index 0000000000..c6fdd22500 --- /dev/null +++ b/packages/app/src/assets/acp-provider-icons/hermes.svg @@ -0,0 +1,3 @@ + + + diff --git a/packages/app/src/assets/acp-provider-icons/kiro.svg b/packages/app/src/assets/acp-provider-icons/kiro.svg new file mode 100644 index 0000000000..31715c335a --- /dev/null +++ b/packages/app/src/assets/acp-provider-icons/kiro.svg @@ -0,0 +1 @@ + diff --git a/packages/app/src/assets/acp-provider-icons/minimax-code.svg b/packages/app/src/assets/acp-provider-icons/minimax-code.svg new file mode 100644 index 0000000000..61fcb8afab --- /dev/null +++ b/packages/app/src/assets/acp-provider-icons/minimax-code.svg @@ -0,0 +1,3 @@ + + + diff --git a/packages/app/src/assets/acp-provider-icons/traecli.svg b/packages/app/src/assets/acp-provider-icons/traecli.svg new file mode 100644 index 0000000000..6d5388fcaa --- /dev/null +++ b/packages/app/src/assets/acp-provider-icons/traecli.svg @@ -0,0 +1,3 @@ + + + diff --git a/packages/app/src/command-center/command-center.tsx b/packages/app/src/command-center/command-center.tsx index 607f24c214..febac60a14 100644 --- a/packages/app/src/command-center/command-center.tsx +++ b/packages/app/src/command-center/command-center.tsx @@ -16,7 +16,10 @@ import { Check, ChevronRight, Folder, X } from "lucide-react-native"; import { StyleSheet, withUnistyles } from "react-native-unistyles"; import { BottomSheetFlatList, type BottomSheetFlatListMethods } from "@gorhom/bottom-sheet"; import { AgentStatusDot } from "@/components/agent-status-dot"; +import { HighlightedText, type HighlightedTextProps } from "@/components/ui/highlighted-text"; +import { findHighlightRanges } from "@/components/ui/highlighted-text-segments"; import { MaterialFileIcon } from "@/components/material-file-icon"; +import { ProjectIconView } from "@/components/project-icon-view"; import { LoadingSpinner } from "@/components/ui/loading-spinner"; import { EditingTextInput as TextInput, @@ -29,8 +32,11 @@ import { } from "@/components/ui/isolated-bottom-sheet-modal"; import { useIsCompactFormFactor } from "@/constants/layout"; import { isNative, isWeb } from "@/constants/platform"; -import { useAggregatedAgents, type AggregatedAgent } from "@/hooks/use-aggregated-agents"; +import { useAggregatedAgents } from "@/hooks/use-aggregated-agents"; import { useProjects } from "@/hooks/use-projects"; +import { useTimeAgo } from "@/hooks/use-time-ago"; +import { createProjectIconTarget } from "@/projects/icon-target"; +import { useProjectIcons } from "@/projects/icons"; import { OverlayLayerProvider, useGlobalWebOverlayLayer, @@ -49,8 +55,14 @@ import { } from "@/utils/command-center-focus-restore"; import { focusWithRetries } from "@/utils/web-focus"; import { navigateToAgent } from "@/utils/navigate-to-agent"; -import { formatTimeAgo } from "@/utils/time"; import { shortenPath } from "@/utils/shorten-path"; +import { projectIconPlaceholderLabelFromDisplayName } from "@/utils/project-display-name"; +import { + COMMAND_CENTER_LINE_HEIGHT, + COMMAND_CENTER_LIST_METRICS, + COMMAND_CENTER_SECTION_GAP, + type CommandCenterListMetrics, +} from "./list-metrics"; import { useCommandCenterContributions } from "./provider"; import { filterAndRankWorkspaces } from "./workspace-search"; import { @@ -89,42 +101,14 @@ const ThemedLoadingSpinner = withUnistyles(LoadingSpinner, (theme) => ({ const COMMAND_CENTER_SNAP_POINTS = ["60%", "90%"]; const KEYBOARD_SHOULD_PERSIST_TAPS = "always" as const; -function sortAgents(left: AggregatedAgent, right: AggregatedAgent): number { - const leftNeedsInput = (left.pendingPermissionCount ?? 0) > 0 ? 1 : 0; - const rightNeedsInput = (right.pendingPermissionCount ?? 0) > 0 ? 1 : 0; - if (leftNeedsInput !== rightNeedsInput) return rightNeedsInput - leftNeedsInput; - const leftAttention = left.requiresAttention ? 1 : 0; - const rightAttention = right.requiresAttention ? 1 : 0; - if (leftAttention !== rightAttention) return rightAttention - leftAttention; - const leftRunning = left.status === "running" ? 1 : 0; - const rightRunning = right.status === "running" ? 1 : 0; - if (leftRunning !== rightRunning) return rightRunning - leftRunning; - return right.lastActivityAt.getTime() - left.lastActivityAt.getTime(); -} - -function compareWorkspacesByTitle( - left: CommandCenterWorkspaceResult, - right: CommandCenterWorkspaceResult, -): number { - const titleDelta = left.title.localeCompare(right.title, undefined, { - numeric: true, - sensitivity: "base", - }); - return titleDelta || left.subtitle.localeCompare(right.subtitle); -} - /** `cwd` is not rendered, so a path match must never outrank a match on text the user can see. */ function agentSearchFields(result: CommandCenterAgentResult): CommandCenterSearchFields { return { visible: [result.title, result.subtitle], hidden: [result.agent.cwd] }; } /** - * Build every pinned row, in its default order. Deliberately not keyed on `query`: none of this - * work depends on what was typed, and rebuilding it per keystroke means re-running an Intl - * collation sort over every workspace. - * - * The cost is that `formatTimeAgo` is baked into the agent subtitle here, so relative timestamps - * now refresh when agents or projects change rather than on every keystroke. + * Build every pinned row. Deliberately not keyed on `query`: none of this work depends on what + * was typed. Ordering belongs to `filterAndRankBuiltInResults`, which ranks on every keystroke. */ function useBuiltInRows(open: boolean): { workspaces: CommandCenterWorkspaceResult[]; @@ -134,11 +118,32 @@ function useBuiltInRows(open: boolean): { const { agents } = useAggregatedAgents({ demand: open }); const { projects } = useProjects({ enabled: open }); const showHost = useHosts().length > 1; + const iconTargets = useMemo( + () => + open + ? projects.flatMap((project) => + project.hosts.flatMap((host) => { + const target = createProjectIconTarget({ + projectViewKey: project.viewKey, + placement: { ...host, iconWorkingDir: host.repoRoot }, + }); + return target ? [target] : []; + }), + ) + : [], + [open, projects], + ); + const iconDataByProjectViewKey = useProjectIcons({ projects: iconTargets }); return useMemo(() => { if (!open) return { workspaces: [], agents: [] }; const allWorkspaces: CommandCenterWorkspaceResult[] = []; for (const project of projects) { + const workspaceProject = { + viewKey: project.viewKey, + name: project.projectName, + iconDataUri: iconDataByProjectViewKey.get(project.viewKey) ?? null, + }; for (const host of project.hosts) { for (const workspace of host.workspaces) { if (workspace.archivingAt) continue; @@ -151,7 +156,9 @@ function useBuiltInRows(open: boolean): { project.projectName, workspace.currentBranch, ]), + project: workspaceProject, changeRequestNumber: workspace.changeRequestNumber, + activityAt: workspace.statusEnteredAt, run: () => { clearCommandCenterFocusRestoreElement(); navigateToWorkspace({ serverId: host.serverId, workspaceId: workspace.id }); @@ -160,34 +167,31 @@ function useBuiltInRows(open: boolean): { } } } - allWorkspaces.sort(compareWorkspacesByTitle); const workspaceTitleByKey = new Map( allWorkspaces.map((workspace) => [workspace.id.slice("workspace:".length), workspace.title]), ); - const agentRows = agents - .map((agent) => { - const workspaceTitle = agent.workspaceId - ? workspaceTitleByKey.get(`${agent.serverId}:${agent.workspaceId}`) - : undefined; - return { - kind: "agent", - id: `agent:${agent.serverId}:${agent.id}`, - agent, - title: agent.title || t("shell.commandCenter.newAgent"), - subtitle: joinSubtitleParts([ - showHost ? agent.serverLabel : null, - workspaceTitle ?? shortenPath(agent.cwd), - formatTimeAgo(agent.lastActivityAt), - ]), - run: () => { - clearCommandCenterFocusRestoreElement(); - navigateToAgent({ serverId: agent.serverId, agentId: agent.id }); - }, - }; - }) - .sort((left, right) => sortAgents(left.agent, right.agent)); + const agentRows = agents.map((agent) => { + const workspaceTitle = agent.workspaceId + ? workspaceTitleByKey.get(`${agent.serverId}:${agent.workspaceId}`) + : undefined; + return { + kind: "agent", + id: `agent:${agent.serverId}:${agent.id}`, + agent, + title: agent.title || t("shell.commandCenter.newAgent"), + subtitle: joinSubtitleParts([ + showHost ? agent.serverLabel : null, + workspaceTitle ?? shortenPath(agent.cwd), + ]), + activityAt: agent.lastActivityAt, + run: () => { + clearCommandCenterFocusRestoreElement(); + navigateToAgent({ serverId: agent.serverId, agentId: agent.id }); + }, + }; + }); return { workspaces: allWorkspaces, agents: agentRows }; - }, [agents, open, projects, showHost, t]); + }, [agents, iconDataByProjectViewKey, open, projects, showHost, t]); } function useBuiltInSections(open: boolean, query: string): CommandCenterResultSection[] { @@ -202,16 +206,14 @@ function useBuiltInSections(open: boolean, query: string): CommandCenterResultSe band: PINNED_SECTION_BAND, rank: 2, title: t("shell.commandCenter.workspaces"), - results: filterAndRankWorkspaces(rows.workspaces, query, compareWorkspacesByTitle), + results: filterAndRankWorkspaces(rows.workspaces, query), }, { id: "agents", band: PINNED_SECTION_BAND, rank: 3, title: t("shell.commandCenter.agents"), - results: filterAndRankBuiltInResults(rows.agents, query, agentSearchFields, (left, right) => - sortAgents(left.agent, right.agent), - ), + results: filterAndRankBuiltInResults(rows.agents, query, agentSearchFields), }, ]; }, [open, query, rows, t]); @@ -236,7 +238,7 @@ interface CommandCenterState { key(key: string): boolean; } -function useCommandCenterState(): CommandCenterState { +function useCommandCenterState(listMetrics: CommandCenterListMetrics): CommandCenterState { const keyboardActionDispatcher = useKeyboardActionDispatcher(); const { t } = useTranslation(); const open = useKeyboardShortcutsStore((state) => state.commandCenterOpen); @@ -290,8 +292,9 @@ function useCommandCenterState(): CommandCenterState { scope === "files" ? fileSections : [...contributionSections, ...fileSections, ...builtInSections], + listMetrics, ), - [builtInSections, contributionSections, fileSections, scope], + [builtInSections, contributionSections, fileSections, listMetrics, scope], ); const resolvedActiveId = preserveActiveResultId(activeId, projection.selectableResults); @@ -381,11 +384,19 @@ function useCommandCenterState(): CommandCenterState { interface ResultRowProps { result: CommandCenterResult; + height: number; + query: string; active: boolean; onSelect(result: CommandCenterResult): void; } -const ResultRow = memo(function ResultRow({ result, active, onSelect }: ResultRowProps) { +const ResultRow = memo(function ResultRow({ + result, + height, + query, + active, + onSelect, +}: ResultRowProps) { const press = useCallback(() => onSelect(result), [onSelect, result]); const choice = result.kind === "contribution" && result.contribution.presentation.kind === "choice" @@ -402,15 +413,10 @@ const ResultRow = memo(function ResultRow({ result, active, onSelect }: ResultRo const style = useCallback( ({ hovered, pressed }: PressableStateCallbackType & { hovered?: boolean }) => [ styles.row, - (result.kind === "agent" || - result.kind === "workspace" || - (result.kind === "contribution" && - result.contribution.presentation.kind === "action" && - Boolean(result.contribution.presentation.subtitle))) && - styles.tallRow, + { height }, (Boolean(hovered) || pressed || active) && styles.activeRow, ], - [active, result], + [active, height], ); return ( - + ); }); -function ResultContent({ result }: { result: CommandCenterResult }) { +/** + * Text with the query's terms marked. Marks use the same matcher options the rows were ranked + * with, so a mark always points at something that made the row match. + */ +function QueryHighlightedText({ + query, + text, + ...props +}: { query: string } & Omit) { + const ranges = useMemo(() => findHighlightRanges(query, text), [query, text]); + return ; +} + +/** + * The subtitle line of a workspace or agent row. The timestamp is its own text so a long branch + * truncates without pushing the time out of view, and so the time is never part of what the + * query matches against. It keeps itself current while the command center stays open. + */ +function SubtitleWithTimestamp({ + query, + subtitle, + activityAt, + testID, +}: { + query: string; + subtitle: string; + activityAt: Date | null; + testID: string; +}) { + const timeAgo = useTimeAgo(activityAt); + return ( + + + {timeAgo ? ( + + {/* Non-breaking: web collapses a leading plain space in its own flex item. */} + {subtitle ? `\u00a0· ${timeAgo}` : timeAgo} + + ) : null} + + ); +} + +/** The same project icon the sidebar's workspace rows lead with: its image, or a lettered square. */ +function WorkspaceProjectIcon({ project }: { project: CommandCenterWorkspaceResult["project"] }) { + const initial = projectIconPlaceholderLabelFromDisplayName(project.name).charAt(0).toUpperCase(); + return ( + + ); +} + +function ResultContent({ result, query }: { result: CommandCenterResult; query: string }) { if (result.kind === "file") { return ( @@ -438,13 +507,16 @@ function ResultContent({ result }: { result: CommandCenterResult }) { - - {result.title} - + {result.subtitle ? ( {" "} - {result.subtitle} + ) : null} @@ -465,12 +537,18 @@ function ResultContent({ result }: { result: CommandCenterResult }) { /> - - {result.title} - - - {result.subtitle} - + + @@ -481,20 +559,28 @@ function ResultContent({ result }: { result: CommandCenterResult }) { return ( - - + {/* Decorative: the fallback icon's initial must not prefix the row's accessible name. */} + + - - {result.title} - - + - {result.subtitle} - + /> @@ -512,11 +598,19 @@ function ResultContent({ result }: { result: CommandCenterResult }) { ) : null} - - {presentation.title} - + {presentation.subtitle ? ( - {presentation.subtitle} + ) : null} @@ -541,14 +635,14 @@ function ResultContent({ result }: { result: CommandCenterResult }) { style={styles.breadcrumbPart} > {index > 0 ? : null} - - {part} - + /> ))} @@ -563,11 +657,9 @@ function ResultContent({ result }: { result: CommandCenterResult }) { } function SectionRow({ row }: { row: Extract }) { - let sizeStyle = styles.dividerSection; - if (row.title && row.divider) sizeStyle = styles.dividedSection; - if (row.title && !row.divider) sizeStyle = styles.titledSection; + const style = useMemo(() => [styles.section, { height: row.height }], [row.height]); return ( - + {row.divider ? : null} {row.title ? {row.title} : null} @@ -576,8 +668,10 @@ function SectionRow({ row }: { row: Extract>(null); @@ -644,11 +738,13 @@ export function CommandCenter() { ) : ( ), - [state.activeId, state.select], + [state.activeId, state.query, state.select], ); const getItemLayout = useCallback( (_data: ArrayLike | null | undefined, index: number) => ({ @@ -901,20 +997,21 @@ const styles = StyleSheet.create((theme) => ({ fontWeight: "500", }, results: { flex: 1 }, + // Sections and rows take their height from list-metrics; these styles only place content in it. + section: { justifyContent: "flex-end" }, sectionLabel: { paddingHorizontal: theme.spacing[4], - paddingBottom: theme.spacing[2], + paddingBottom: COMMAND_CENTER_SECTION_GAP, fontSize: theme.fontSize.sm, + lineHeight: COMMAND_CENTER_LINE_HEIGHT.sectionLabel, color: theme.colors.foregroundMuted, }, sectionDivider: { height: 1, - marginTop: theme.spacing[2], - marginBottom: theme.spacing[2], + marginVertical: COMMAND_CENTER_SECTION_GAP, backgroundColor: theme.colors.border, }, - row: { height: 36, paddingHorizontal: theme.spacing[4], paddingVertical: theme.spacing[2] }, - tallRow: { height: 56 }, + row: { paddingHorizontal: theme.spacing[4], justifyContent: "center" }, activeRow: { backgroundColor: theme.colors.surface1 }, rowContent: { flexDirection: "row", @@ -933,14 +1030,31 @@ const styles = StyleSheet.create((theme) => ({ title: { color: theme.colors.foreground, fontSize: theme.fontSize.base, - lineHeight: 18, + lineHeight: COMMAND_CENTER_LINE_HEIGHT.title, flexShrink: 1, }, - fileLine: { flex: 1, minWidth: 0, fontSize: theme.fontSize.base, lineHeight: 20 }, + fileLine: { + flex: 1, + minWidth: 0, + fontSize: theme.fontSize.base, + lineHeight: COMMAND_CENTER_LINE_HEIGHT.singleLine, + }, fileName: { color: theme.colors.foreground }, filePath: { color: theme.colors.foregroundMuted }, - subtitle: { color: theme.colors.foregroundMuted, fontSize: theme.fontSize.sm, lineHeight: 16 }, - iconSlot: { width: 16, height: 20, alignItems: "center", justifyContent: "center" }, + subtitle: { + color: theme.colors.foregroundMuted, + fontSize: theme.fontSize.sm, + lineHeight: COMMAND_CENTER_LINE_HEIGHT.subtitle, + }, + subtitleLine: { flexDirection: "row", minWidth: 0 }, + subtitleText: { flexShrink: 1, minWidth: 0 }, + iconSlot: { + width: 16, + height: COMMAND_CENTER_LINE_HEIGHT.singleLine, + alignItems: "center", + justifyContent: "center", + }, + projectIconFallbackText: { fontSize: 9 }, rowShortcut: { flexShrink: 0 }, breadcrumb: { flex: 1, @@ -958,7 +1072,7 @@ const styles = StyleSheet.create((theme) => ({ breadcrumbGroup: { color: theme.colors.foregroundMuted, fontSize: theme.fontSize.base, - lineHeight: 20, + lineHeight: COMMAND_CENTER_LINE_HEIGHT.singleLine, flexShrink: 0, }, emptyText: { @@ -978,7 +1092,4 @@ const styles = StyleSheet.create((theme) => ({ }, sheetBackground: { backgroundColor: theme.colors.surface0 }, sheetHandle: { backgroundColor: theme.colors.palette.zinc[600] }, - titledSection: { height: 32, justifyContent: "flex-end" }, - dividedSection: { height: 49, justifyContent: "flex-end" }, - dividerSection: { height: 17, justifyContent: "flex-end" }, })); diff --git a/packages/app/src/command-center/list-metrics.ts b/packages/app/src/command-center/list-metrics.ts new file mode 100644 index 0000000000..603fc91e4c --- /dev/null +++ b/packages/app/src/command-center/list-metrics.ts @@ -0,0 +1,53 @@ +import { SPACING } from "@/styles/theme"; + +/** + * Every vertical size in the Command Center list, in one place. + * + * The list is virtualized, so it needs each row's height before rendering it. Rather than keep + * those numbers in sync with the styles by hand, rows render at exactly the height computed here + * and center their content. The styles read the line heights below, so this arithmetic is the + * layout. + * + * A layout chooses one thing: the inset above and below a row's text. Both layouts share the same + * shape, so nothing downstream asks which one it got. + */ +export const COMMAND_CENTER_LINE_HEIGHT = { + /** A row with no subtitle. Also the icon slot, so the icon centers on the title. */ + singleLine: 20, + title: 18, + subtitle: 16, + sectionLabel: 16, +} as const; + +/** Space around a section's label and around the rule between sections. */ +export const COMMAND_CENTER_SECTION_GAP = SPACING[2]; +const SECTION_DIVIDER_THICKNESS = 1; + +export interface CommandCenterListMetrics { + singleLineRow: number; + twoLineRow: number; + /** A section label and the gaps around it. */ + sectionTitle: number; + /** The rule between two sections and the gaps around it. */ + sectionDivider: number; +} + +function listMetrics(rowInset: number): CommandCenterListMetrics { + const line = COMMAND_CENTER_LINE_HEIGHT; + return { + singleLineRow: rowInset + line.singleLine + rowInset, + twoLineRow: rowInset + line.title + line.subtitle + rowInset, + sectionTitle: COMMAND_CENTER_SECTION_GAP + line.sectionLabel + COMMAND_CENTER_SECTION_GAP, + sectionDivider: + COMMAND_CENTER_SECTION_GAP + SECTION_DIVIDER_THICKNESS + COMMAND_CENTER_SECTION_GAP, + }; +} + +/** + * Desktop is dense for a pointer. Compact keeps single-line rows at the 44pt touch height that + * `density.rowHeight` uses on compact layouts. + */ +export const COMMAND_CENTER_LIST_METRICS = { + desktop: listMetrics(SPACING[1.5]), + compact: listMetrics(SPACING[3]), +} as const satisfies Record; diff --git a/packages/app/src/command-center/results.test.ts b/packages/app/src/command-center/results.test.ts index 4f6a43d704..688352f00f 100644 --- a/packages/app/src/command-center/results.test.ts +++ b/packages/app/src/command-center/results.test.ts @@ -1,5 +1,6 @@ import { describe, expect, it } from "vitest"; import type { CommandCenterContribution } from "./contributions"; +import { COMMAND_CENTER_LIST_METRICS } from "./list-metrics"; import { buildContributionSections, filterAndRankBuiltInResults, @@ -101,17 +102,28 @@ function autoModeChoice(): CommandCenterContribution { }); } -function workspace(id: string, title = id, subtitle = "host"): CommandCenterWorkspaceResult { +function workspace( + id: string, + title = id, + subtitle = "host", + activityAt: Date | null = null, +): CommandCenterWorkspaceResult { return { kind: "workspace", id, title, subtitle, + project: { viewKey: "project", name: "project", iconDataUri: null }, changeRequestNumber: null, + activityAt, run: () => undefined, }; } +function minutesAgo(minutes: number): Date { + return new Date(Date.UTC(2026, 9, 18, 12, 0) - minutes * 60_000); +} + function sectionResultIds(sections: ReturnType): string[] { const ids: string[] = []; for (const section of sections) { @@ -120,6 +132,8 @@ function sectionResultIds(sections: ReturnType return ids; } +const metrics = COMMAND_CENTER_LIST_METRICS.desktop; + describe("Command Center result projection", () => { it("query-gates model choices and creates one flat row index", () => { const contributions = [ @@ -130,16 +144,19 @@ describe("Command Center result projection", () => { expect(sectionResultIds(emptySections)).toEqual(["settings"]); const sections = buildContributionSections(contributions, "o"); - const projection = projectCommandCenterRows([ - ...sections, - { - id: "workspaces", - band: PINNED_SECTION_BAND, - rank: 2, - title: "Workspaces", - results: [workspace("workspace:1")], - }, - ]); + const projection = projectCommandCenterRows( + [ + ...sections, + { + id: "workspaces", + band: PINNED_SECTION_BAND, + rank: 2, + title: "Workspaces", + results: [workspace("workspace:1")], + }, + ], + metrics, + ); expect(projection.rows.map((row) => row.key)).toEqual([ "section:models", "opus", @@ -147,7 +164,12 @@ describe("Command Center result projection", () => { "workspace:1", ]); expect(projection.rowIndexByResultId.get("workspace:1")).toBe(3); - expect(projection.offsets).toEqual([0, 32, 68, 117]); + expect(projection.offsets).toEqual([ + 0, + metrics.sectionTitle, + metrics.sectionTitle + metrics.singleLineRow, + metrics.sectionTitle + metrics.singleLineRow + metrics.sectionDivider + metrics.sectionTitle, + ]); }); it("shows query-only actions only when their group matches a search", () => { @@ -177,15 +199,18 @@ describe("Command Center result projection", () => { it("keeps keyboard selection aligned with rows beyond the render window", () => { const workspaces = Array.from({ length: 200 }, (_, index) => workspace(`workspace:${index}`)); - const projection = projectCommandCenterRows([ - { - id: "workspaces", - band: PINNED_SECTION_BAND, - rank: 0, - title: "Workspaces", - results: workspaces, - }, - ]); + const projection = projectCommandCenterRows( + [ + { + id: "workspaces", + band: PINNED_SECTION_BAND, + rank: 0, + title: "Workspaces", + results: workspaces, + }, + ], + metrics, + ); let activeId: string | null = workspaces[0].id; for (let index = 0; index < 150; index += 1) { @@ -195,7 +220,7 @@ describe("Command Center result projection", () => { const targetId = workspaces[150].id; expect(activeId).toBe(targetId); expect(projection.rowIndexByResultId.get(targetId)).toBe(151); - expect(projection.offsets[151]).toBe(32 + 150 * 56); + expect(projection.offsets[151]).toBe(metrics.sectionTitle + 150 * metrics.twoLineRow); }); }); @@ -248,7 +273,7 @@ describe("Command Center relevance ordering", () => { schedulesAction(), action({ id: "new-agent", group: "workspace", groupRank: -1, title: "New agent" }), ]; - const projection = projectCommandCenterRows(buildContributionSections(shuffled, "")); + const projection = projectCommandCenterRows(buildContributionSections(shuffled, ""), metrics); // Query-gated choices stay hidden; the rest fall back to groupRank, unchanged by this feature. expect(projection.selectableResults.map((result) => result.id)).toEqual([ @@ -301,16 +326,19 @@ describe("Command Center relevance ordering", () => { }); it("keeps Workspaces below contributions even on a perfect match", () => { - const projection = projectCommandCenterRows([ - ...buildContributionSections([schedulesAction()], "auto"), - { - id: "workspaces", - band: PINNED_SECTION_BAND, - rank: 2, - title: "Workspaces", - results: [workspace("auto")], - }, - ]); + const projection = projectCommandCenterRows( + [ + ...buildContributionSections([schedulesAction()], "auto"), + { + id: "workspaces", + band: PINNED_SECTION_BAND, + rank: 2, + title: "Workspaces", + results: [workspace("auto")], + }, + ], + metrics, + ); expect(projection.selectableResults.map((result) => result.id)).toEqual(["schedules", "auto"]); }); @@ -324,7 +352,7 @@ describe("Command Center relevance ordering", () => { title: "Workspaces", results: [workspace("auto")], }; - const projection = projectCommandCenterRows([workspaces, ...sections.toReversed()]); + const projection = projectCommandCenterRows([workspaces, ...sections.toReversed()], metrics); expect(projection.selectableResults.map((result) => result.id)).toEqual([ "mode:auto", @@ -461,15 +489,19 @@ describe("filterAndRankBuiltInResults", () => { visible: [row.title, row.subtitle], hidden: [], }); - const byTitle = (left: CommandCenterWorkspaceResult, right: CommandCenterWorkspaceResult) => - left.title.localeCompare(right.title); - it("caps an empty query and preserves the caller's order", () => { - const rows = Array.from({ length: 8 }, (_, index) => workspace(`w${index}`)); + it("shows the five most recent rows for an empty query", () => { + const rows = Array.from({ length: 8 }, (_, index) => + workspace(`w${index}`, `w${index}`, "host", minutesAgo(8 - index)), + ); - expect( - filterAndRankBuiltInResults(rows, "", visibleOnly, byTitle).map((row) => row.id), - ).toEqual(["w0", "w1", "w2", "w3", "w4"]); + expect(filterAndRankBuiltInResults(rows, "", visibleOnly).map((row) => row.id)).toEqual([ + "w7", + "w6", + "w5", + "w4", + "w3", + ]); }); it("puts the best match first even when it sorts last alphabetically", () => { @@ -480,9 +512,9 @@ describe("filterAndRankBuiltInResults", () => { ]; // Alphabetically this is Alpha, Label, Zebra. "lab des" only matches Label as Design. - expect( - filterAndRankBuiltInResults(rows, "lab des", visibleOnly, byTitle).map((row) => row.id), - ).toEqual(["c"]); + expect(filterAndRankBuiltInResults(rows, "lab des", visibleOnly).map((row) => row.id)).toEqual([ + "c", + ]); }); it("ranks a title match above a match that only the hidden field reached", () => { @@ -492,24 +524,41 @@ describe("filterAndRankBuiltInResults", () => { ? { visible: [row.title], hidden: ["deploy"] } : { visible: [row.title], hidden: [] }; - expect( - filterAndRankBuiltInResults(rows, "deploy", fields, byTitle).map((row) => row.id), - ).toEqual(["title-hit", "hidden-hit"]); + expect(filterAndRankBuiltInResults(rows, "deploy", fields).map((row) => row.id)).toEqual([ + "title-hit", + "hidden-hit", + ]); }); - it("breaks an equal score with the caller's tiebreak, not with match order", () => { - // Both titles are an exact prefix match for "task", so only the tiebreak separates them. - const rows = [workspace("second", "Task zebra"), workspace("first", "Task alpha")]; + it("orders rows in the same match tier by recency, not by where the word sits", () => { + // Both are whole-word matches for "usage"; the older one finds it earlier in the title. + const rows = [ + workspace("older", "Deliver sidebar usage", "host", minutesAgo(60)), + workspace("newer", "design the cli interface to expose usage data", "host", minutesAgo(5)), + ]; - expect( - filterAndRankBuiltInResults(rows, "task", visibleOnly, byTitle).map((row) => row.id), - ).toEqual(["first", "second"]); + expect(filterAndRankBuiltInResults(rows, "usage", visibleOnly).map((row) => row.id)).toEqual([ + "newer", + "older", + ]); + }); + + it("keeps a better match tier above a more recent weaker match", () => { + const rows = [ + workspace("subsequence", "Fix stuck toast", "fix/updating-messages", minutesAgo(1)), + workspace("whole-word", "Usage hover card", "host", minutesAgo(600)), + ]; + + expect(filterAndRankBuiltInResults(rows, "usage", visibleOnly).map((row) => row.id)).toEqual([ + "whole-word", + "subsequence", + ]); }); it("drops a row when one token matches nothing", () => { const rows = [workspace("a", "Label as Design")]; - expect(filterAndRankBuiltInResults(rows, "lab zzz", visibleOnly, byTitle)).toEqual([]); + expect(filterAndRankBuiltInResults(rows, "lab zzz", visibleOnly)).toEqual([]); }); }); diff --git a/packages/app/src/command-center/results.ts b/packages/app/src/command-center/results.ts index 8f3528cd2c..84fc91d3f0 100644 --- a/packages/app/src/command-center/results.ts +++ b/packages/app/src/command-center/results.ts @@ -5,6 +5,7 @@ import { scoreTextFields, } from "@getpaseo/protocol/search/text-match"; import type { CommandCenterContribution } from "./contributions"; +import type { CommandCenterListMetrics } from "./list-metrics"; /** Sections that reorder by how well they match the query. */ export const CONTRIBUTION_SECTION_BAND = 0; @@ -43,13 +44,21 @@ export function compareCommandCenterScores( return left.fieldRank - right.fieldRank || compareMatchScores(left.match, right.match); } +export interface CommandCenterWorkspaceProject { + viewKey: string; + name: string; + iconDataUri: string | null; +} + export interface CommandCenterWorkspaceResult { kind: "workspace"; id: string; title: string; subtitle: string; + project: CommandCenterWorkspaceProject; /** PR/MR number backing this workspace, so a number query can match it exactly. */ changeRequestNumber: number | null; + activityAt: Date | null; run(): void; } @@ -59,6 +68,7 @@ export interface CommandCenterAgentResult { agent: AggregatedAgent; title: string; subtitle: string; + activityAt: Date | null; run(): void; } @@ -169,13 +179,12 @@ function contributionSearchFields( return { visible, hidden: contribution.keywords }; } -function resultHeight(result: CommandCenterResult): number { - if (result.kind === "workspace" || result.kind === "agent") return 56; - if (result.kind === "file") return 36; - if (result.contribution.presentation.kind === "action") { - return result.contribution.presentation.subtitle ? 56 : 36; - } - return 36; +/** Whether the row draws a second, subtitle line under its title. */ +function hasSubtitleLine(result: CommandCenterResult): boolean { + if (result.kind === "workspace" || result.kind === "agent") return true; + if (result.kind === "file") return false; + const presentation = result.contribution.presentation; + return presentation.kind === "action" && Boolean(presentation.subtitle); } /** @@ -203,22 +212,42 @@ function resultScore(result: CommandCenterResult): CommandCenterScore | undefine /** Rows shown when nothing has been typed, per pinned category. */ const DEFAULT_CATEGORY_RESULT_LIMIT = 5; +/** A built-in row (workspace or agent) that orders by how recently it saw activity. */ +export interface CommandCenterRecentRow { + activityAt: Date | null; +} + +/** Most recent first. A row with no timestamp sorts after every row that has one. */ +export function compareByRecency(left: CommandCenterRecentRow, right: CommandCenterRecentRow) { + return (right.activityAt?.getTime() ?? 0) - (left.activityAt?.getTime() ?? 0); +} + +/** + * Rank built-in rows by the kind of match they made: which fields matched, then the matcher's + * tier. Offset and spread are deliberately left out. They only say where in the title the word + * happened to sit, so "usage" in "Deliver sidebar usage" and in "expose usage data" would be + * ordered by sentence position. Leaving them out makes those rows equal, and recency decides. + */ +export function compareBuiltInScores(left: CommandCenterScore, right: CommandCenterScore): number { + return left.fieldRank - right.fieldRank || left.match.tier - right.match.tier; +} + /** * Filter and rank already-built rows. Rows in, rows out — building them needs translations, * navigation callbacks and the project tree, none of which matching cares about, so that stays * with the caller and this stays testable without mounting React. * - * `tiebreak` is the caller's own ordering (alphabetical for workspaces, status and recency for - * agents). It decides equal-scoring rows, so an agent awaiting input still outranks an idle one - * that matched exactly as well. + * Rows rank by `compareBuiltInScores`; rows that rank equally, including every row of an empty + * query, go most recent first. */ -export function filterAndRankBuiltInResults( +export function filterAndRankBuiltInResults( rows: readonly Row[], query: string, fieldsOf: (row: Row) => CommandCenterSearchFields, - tiebreak: (left: Row, right: Row) => number, ): Row[] { - if (!query.trim()) return rows.slice(0, DEFAULT_CATEGORY_RESULT_LIMIT); + if (!query.trim()) { + return [...rows].sort(compareByRecency).slice(0, DEFAULT_CATEGORY_RESULT_LIMIT); + } const scored: { row: Row; score: CommandCenterScore }[] = []; for (const row of rows) { @@ -227,7 +256,7 @@ export function filterAndRankBuiltInResults( } scored.sort( (left, right) => - compareCommandCenterScores(left.score, right.score) || tiebreak(left.row, right.row), + compareBuiltInScores(left.score, right.score) || compareByRecency(left.row, right.row), ); return scored.map((entry) => entry.row); } @@ -293,6 +322,7 @@ export function buildContributionSections( export function projectCommandCenterRows( sections: readonly CommandCenterResultSection[], + metrics: CommandCenterListMetrics, ): CommandCenterListProjection { const populated = sections .filter((section) => section.results.length > 0) @@ -305,10 +335,8 @@ export function projectCommandCenterRows( for (const [sectionIndex, section] of populated.entries()) { const divider = sectionIndex > 0; - let sectionHeight = 0; - if (section.title && divider) sectionHeight = 49; - if (section.title && !divider) sectionHeight = 32; - if (!section.title && divider) sectionHeight = 17; + const sectionHeight = + (divider ? metrics.sectionDivider : 0) + (section.title ? metrics.sectionTitle : 0); if (sectionHeight > 0) { offsets.push(offset); rows.push({ @@ -321,7 +349,7 @@ export function projectCommandCenterRows( offset += sectionHeight; } for (const result of section.results) { - const height = resultHeight(result); + const height = hasSubtitleLine(result) ? metrics.twoLineRow : metrics.singleLineRow; offsets.push(offset); rowIndexByResultId.set(result.id, rows.length); rows.push({ kind: "result", key: result.id, result, height }); diff --git a/packages/app/src/command-center/workspace-contributions.ts b/packages/app/src/command-center/workspace-contributions.ts index afc484de57..538905cb4a 100644 --- a/packages/app/src/command-center/workspace-contributions.ts +++ b/packages/app/src/command-center/workspace-contributions.ts @@ -1,4 +1,4 @@ -import type { GitAction, GitActions } from "@/git/policy"; +import { actionsWithoutPrimary, type GitAction, type GitActions } from "@/git/policy"; import type { KeyboardActionDefinition } from "@/keyboard/keyboard-action-dispatcher"; import type { WorkspacePanelPlacement, @@ -581,9 +581,7 @@ export function buildWorkspaceCommandCenterContributions( ...(source.capabilities.canSplitPanes ? buildPaneContributions(source) : []), ]; - const primary = source.gitActions.primary; - for (const [index, action] of source.gitActions.secondary.entries()) { - if (action.id === primary?.id) continue; + for (const [index, action] of actionsWithoutPrimary(source.gitActions).entries()) { contributions.push(buildGitContribution(source, action, 100 + index, "query")); } diff --git a/packages/app/src/command-center/workspace-registration.tsx b/packages/app/src/command-center/workspace-registration.tsx index 70789e5353..cd9d008c55 100644 --- a/packages/app/src/command-center/workspace-registration.tsx +++ b/packages/app/src/command-center/workspace-registration.tsx @@ -41,7 +41,7 @@ import { findPaneById, useWorkspaceLayoutStore, } from "@/stores/workspace-layout-store"; -import { shouldShowWorkspaceSetup, useWorkspaceSetupStore } from "@/stores/workspace-setup-store"; +import { shouldShowWorkspaceSetup } from "@/stores/workspace-setup-store"; import { clearCommandCenterFocusRestoreElement } from "@/utils/command-center-focus-restore"; import { getShortcutOs } from "@/utils/shortcut-platform"; import { @@ -188,6 +188,7 @@ export function useWorkspaceCommandCenterActions(): void { workspaceDirectory: workspace.workspaceDirectory ?? null, currentBranch: workspace.gitRuntime?.currentBranch ?? null, pinnedAt: workspace.pinnedAt ?? null, + setupStatus: workspace.setupStatus ?? null, labels: workspace.labels ?? [], })); const cwd = useWorkspaceDirectory(serverId, workspaceId); @@ -195,12 +196,10 @@ export function useWorkspaceCommandCenterActions(): void { const isPinned = fields?.pinnedAt != null; const isCompact = useIsCompactFormFactor(); const canPin = useHostFeature(serverId, "workspacePinning"); - const persistenceKey = - serverId && fields - ? buildWorkspaceTabPersistenceKey({ serverId, workspaceId: fields.id }) - : null; - const canShowSetup = useWorkspaceSetupStore((state) => - shouldShowWorkspaceSetup(persistenceKey ? (state.snapshots[persistenceKey] ?? null) : null), + const supportsSetupObservation = useHostFeature(serverId, "workspaceSetupObservation"); + const canShowSetup = shouldShowWorkspaceSetup( + fields?.setupStatus ?? null, + supportsSetupObservation, ); const { overrides } = useKeyboardShortcutOverrides(); const { gitActions, isGit } = useGitActions({ diff --git a/packages/app/src/command-center/workspace-search.test.ts b/packages/app/src/command-center/workspace-search.test.ts index 2cdae53dd2..93bb5fc6bf 100644 --- a/packages/app/src/command-center/workspace-search.test.ts +++ b/packages/app/src/command-center/workspace-search.test.ts @@ -7,21 +7,22 @@ function workspace(input: { title?: string; subtitle?: string; changeRequestNumber?: number | null; + activityAt?: Date | null; }): CommandCenterWorkspaceResult { return { kind: "workspace", id: input.id, title: input.title ?? input.id, subtitle: input.subtitle ?? "", + project: { viewKey: "project", name: "project", iconDataUri: null }, changeRequestNumber: input.changeRequestNumber ?? null, + activityAt: input.activityAt ?? null, run: () => undefined, }; } function ids(rows: readonly CommandCenterWorkspaceResult[], query: string): string[] { - return filterAndRankWorkspaces(rows, query, (left, right) => left.id.localeCompare(right.id)).map( - (row) => row.id, - ); + return filterAndRankWorkspaces(rows, query).map((row) => row.id); } describe("filterAndRankWorkspaces", () => { @@ -79,4 +80,18 @@ describe("filterAndRankWorkspaces", () => { const text = workspace({ id: "a-text", title: "Migration 42" }); expect(ids([text, subject], "42")).toEqual(["payments", "a-text"]); }); + + it("orders workspaces in the same match tier by recency", () => { + const older = workspace({ + id: "older", + title: "Usage hover card", + activityAt: new Date("2026-10-01T00:00:00Z"), + }); + const newer = workspace({ + id: "newer", + title: "Deliver sidebar usage", + activityAt: new Date("2026-10-17T00:00:00Z"), + }); + expect(ids([older, newer], "usage")).toEqual(["newer", "older"]); + }); }); diff --git a/packages/app/src/command-center/workspace-search.ts b/packages/app/src/command-center/workspace-search.ts index 317d1f1561..40c7c34d01 100644 --- a/packages/app/src/command-center/workspace-search.ts +++ b/packages/app/src/command-center/workspace-search.ts @@ -1,5 +1,6 @@ import { - compareCommandCenterScores, + compareBuiltInScores, + compareByRecency, filterAndRankBuiltInResults, scoreSearchFields, type CommandCenterScore, @@ -33,29 +34,22 @@ function searchFields(workspace: CommandCenterWorkspaceResult) { return { visible: [workspace.title, workspace.subtitle], hidden: [] }; } -function compareScoredWorkspaces( - left: ScoredWorkspace, - right: ScoredWorkspace, - tiebreak: (left: CommandCenterWorkspaceResult, right: CommandCenterWorkspaceResult) => number, -): number { +function compareScoredWorkspaces(left: ScoredWorkspace, right: ScoredWorkspace): number { if (left.changeRequestHit !== right.changeRequestHit) { return left.changeRequestHit ? -1 : 1; } if (left.score && right.score) { - const scoreDelta = compareCommandCenterScores(left.score, right.score); + const scoreDelta = compareBuiltInScores(left.score, right.score); if (scoreDelta !== 0) return scoreDelta; } - return tiebreak(left.workspace, right.workspace); + return compareByRecency(left.workspace, right.workspace); } export function filterAndRankWorkspaces( workspaces: readonly CommandCenterWorkspaceResult[], query: string, - tiebreak: (left: CommandCenterWorkspaceResult, right: CommandCenterWorkspaceResult) => number, ): CommandCenterWorkspaceResult[] { - if (!query.trim()) { - return filterAndRankBuiltInResults(workspaces, query, searchFields, tiebreak); - } + if (!query.trim()) return filterAndRankBuiltInResults(workspaces, query, searchFields); const changeRequestNumber = parseChangeRequestQuery(query); const matches: ScoredWorkspace[] = []; @@ -65,6 +59,6 @@ export function filterAndRankWorkspaces( changeRequestNumber !== null && workspace.changeRequestNumber === changeRequestNumber; if (score || changeRequestHit) matches.push({ workspace, score, changeRequestHit }); } - matches.sort((left, right) => compareScoredWorkspaces(left, right, tiebreak)); + matches.sort(compareScoredWorkspaces); return matches.map((match) => match.workspace); } diff --git a/packages/app/src/components/agent-list.tsx b/packages/app/src/components/agent-list.tsx index 7da36742ae..b487e53660 100644 --- a/packages/app/src/components/agent-list.tsx +++ b/packages/app/src/components/agent-list.tsx @@ -48,6 +48,8 @@ const DATE_SECTION_ORDER = [ "older", ] as const satisfies readonly DateSectionKey[]; +const HISTORY_MATCH_OPTIONS = { typoTolerant: true } as const; + type FlatListItem = | { type: "header"; key: string; section: DateSectionKey } | { type: "agent"; key: string; agent: AggregatedAgent }; @@ -190,10 +192,11 @@ function SessionRow({ const pendingPermissionCount = agent.pendingPermissionCount ?? 0; const ranges = useMemo( () => ({ - workspace: findHighlightRanges(search ?? "", workspaceName), - title: findHighlightRanges(search ?? "", agent.title ?? ""), - branch: findHighlightRanges(search ?? "", branch), - project: findHighlightRanges(search ?? "", projectName), + // History search matches typo-tolerantly on the daemon, so the marks do too. + workspace: findHighlightRanges(search ?? "", workspaceName, HISTORY_MATCH_OPTIONS), + title: findHighlightRanges(search ?? "", agent.title ?? "", HISTORY_MATCH_OPTIONS), + branch: findHighlightRanges(search ?? "", branch, HISTORY_MATCH_OPTIONS), + project: findHighlightRanges(search ?? "", projectName, HISTORY_MATCH_OPTIONS), }), [search, workspaceName, agent.title, branch, projectName], ); diff --git a/packages/app/src/components/file-pane-render-mode.ts b/packages/app/src/components/file-pane-render-mode.ts deleted file mode 100644 index b1c36ede46..0000000000 --- a/packages/app/src/components/file-pane-render-mode.ts +++ /dev/null @@ -1,17 +0,0 @@ -export type FilePreviewRenderKind = "markdown" | "html"; - -export function isRenderedMarkdownFile(filePath: string): boolean { - const normalizedPath = filePath.trim().toLowerCase(); - return normalizedPath.endsWith(".md") || normalizedPath.endsWith(".markdown"); -} - -function isRenderedHtmlFile(filePath: string): boolean { - const normalizedPath = filePath.trim().toLowerCase(); - return normalizedPath.endsWith(".html") || normalizedPath.endsWith(".htm"); -} - -export function filePreviewRenderKind(filePath: string): FilePreviewRenderKind | null { - if (isRenderedMarkdownFile(filePath)) return "markdown"; - if (isRenderedHtmlFile(filePath)) return "html"; - return null; -} diff --git a/packages/app/src/components/icons/antigravity-icon.tsx b/packages/app/src/components/icons/antigravity-icon.tsx new file mode 100644 index 0000000000..baf2b4c4a6 --- /dev/null +++ b/packages/app/src/components/icons/antigravity-icon.tsx @@ -0,0 +1,17 @@ +import Svg, { Path } from "react-native-svg"; + +interface AntigravityIconProps { + size?: number; + color?: string; +} + +export function AntigravityIcon({ size = 16, color = "currentColor" }: AntigravityIconProps) { + return ( + + + + ); +} diff --git a/packages/app/src/components/icons/kiro-icon.tsx b/packages/app/src/components/icons/kiro-icon.tsx new file mode 100644 index 0000000000..830e9109aa --- /dev/null +++ b/packages/app/src/components/icons/kiro-icon.tsx @@ -0,0 +1,18 @@ +import Svg, { Path } from "react-native-svg"; + +interface KiroIconProps { + size?: number; + color?: string; +} + +export function KiroIcon({ size = 16, color = "currentColor" }: KiroIconProps) { + return ( + + + + ); +} diff --git a/packages/app/src/components/markdown/block-stack.tsx b/packages/app/src/components/markdown/block-stack.tsx new file mode 100644 index 0000000000..e17421a84c --- /dev/null +++ b/packages/app/src/components/markdown/block-stack.tsx @@ -0,0 +1,28 @@ +import type { ReactNode } from "react"; +import { View } from "react-native"; +import { StyleSheet } from "react-native-unistyles"; +import { markdownCopyImageSourcesDataSet } from "@/assistant-selection-copy/markup"; +import { isWeb } from "@/constants/platform"; +import { density } from "@/styles/density"; + +/** Stacks Markdown blocks rendered as separate views with the same gap the text puts between its blocks. */ +export function MarkdownBlockStack({ + imageSources, + children, +}: { + imageSources?: Record; + children: ReactNode; +}) { + return ( + + {children} + + ); +} + +const styles = StyleSheet.create({ + stack: { gap: density.blockGap }, +}); diff --git a/packages/app/src/components/markdown/fence/mermaid/host.web.tsx b/packages/app/src/components/markdown/fence/mermaid/host.web.tsx index fed9afe3a3..9370bc90c0 100644 --- a/packages/app/src/components/markdown/fence/mermaid/host.web.tsx +++ b/packages/app/src/components/markdown/fence/mermaid/host.web.tsx @@ -1,5 +1,5 @@ import { useCallback, useMemo, useState } from "react"; -import { Pressable, View, type TextStyle, type ViewStyle } from "react-native"; +import { Pressable, View, type ViewStyle } from "react-native"; import { Code, Maximize2, Workflow } from "lucide-react-native"; import { useTranslation } from "react-i18next"; import { StyleSheet, withUnistyles } from "react-native-unistyles"; @@ -68,15 +68,6 @@ function MermaidFenceHostImpl({ ], [openFullscreen, showSourcePress, t], ); - const sourceView = useMemo(() => { - const { marginTop, marginBottom, marginVertical, ...sourceTextStyle } = textStyle; - const margins: ViewStyle = { - marginTop: marginTop ?? marginVertical, - marginBottom: marginBottom ?? marginVertical, - }; - const text: TextStyle = sourceTextStyle; - return { container: [margins, sourceContainerStyle], text }; - }, [textStyle]); const diagramStyle = useMemo( () => [ getDiagramBoxStyle(textStyle), @@ -90,19 +81,17 @@ function MermaidFenceHostImpl({ [visible], ); const sourceVisible = !diagramVisible; - const sourceContainer = showSource ? sourceView.container : sourceContainerStyle; - const sourceTextStyle = showSource ? sourceView.text : textStyle; const viewportStyle = diagramVisible ? diagramStyle : measuringStyle; return ( <> {sourceVisible ? ( - + {showSource && canShowDiagram ? ( ; - children: ReactElement; -}) { - return ( - - {children} - - ); -} diff --git a/packages/app/src/components/markdown/renderer.test.ts b/packages/app/src/components/markdown/renderer.test.ts index 8791cf40de..83b6f228dc 100644 --- a/packages/app/src/components/markdown/renderer.test.ts +++ b/packages/app/src/components/markdown/renderer.test.ts @@ -1,6 +1,8 @@ import { fromMarkdown } from "mdast-util-from-markdown"; import { toNativeLinkRecognition } from "react-native-enriched-markdown/src/utils/regexParser"; import { parseMarkdown } from "react-native-enriched-markdown/src/web/parseMarkdown"; +import { recognizeTextLinks } from "react-native-enriched-markdown/src/web/recognizeTextLinks"; +import { classifyAssistantFileLink } from "@/assistant-file-links"; import { markInlineImages } from "react-native-enriched-markdown/src/web/utils"; import type { ASTNode } from "react-native-enriched-markdown/src/web/types"; import { QueryClient } from "@tanstack/react-query"; @@ -112,7 +114,7 @@ it.each([ "src/file.ts:10-20", "src/file.ts(10,2)", ])("recognizes inline paths through the file resolver: %s", (path) => { - const prepared = prepareMarkdownSource(`Open \`${path}\`.`); + const prepared = prepareMarkdownSource(`Open \`${path}\`.`, "/repo"); expect(prepared.linkRecognition.inlineCode?.test(path)).toBe(true); expect(prepared.linkSource(path, "inline-code")).toEqual({ href: path, @@ -121,6 +123,156 @@ it.each([ }); }); +it("preserves stable inline-code file classification through the library parser", async () => { + const paths = [ + "src/app/[id].tsx", + "src/app/(tabs)/index.tsx", + "src/a$b.ts", + ".gitignore", + "src/index.ts#L10-L20", + "src/index.ts:10-20", + "src/index.ts:20-10", + "src/index.ts#L0", + "src/index.ts?raw", + "before/after", + "word.word", + "README.md", + "./scripts/run", + "src/file.ts(10,2)", + "src/file.ts lines 10-20", + "/tmp/[route].tsx", + "file:///tmp/file.ts#L10-L20", + ]; + const source = paths.map((path) => `\`${path}\``).join(" and "); + const prepared = prepareMarkdownSource(source, "/repo"); + const tree = recognizeTextLinks( + await parseMarkdown(prepared.render(), { latexMath: false }), + prepared.linkRecognition.text, + prepared.linkRecognition.inlineCode, + ); + const links: string[] = []; + function collect(node: ASTNode) { + if (node.type === "Link") links.push(String(node.attributes?.url)); + node.children?.forEach(collect); + } + collect(tree); + expect(links).toEqual([ + "src/app/[id].tsx", + "src/app/(tabs)/index.tsx", + "src/a$b.ts", + ".gitignore", + "src/index.ts#L10-L20", + "src/index.ts:10-20", + "README.md", + "./scripts/run", + "src/file.ts(10,2)", + "/tmp/[route].tsx", + "file:///tmp/file.ts#L10-L20", + ]); + expect( + classifyAssistantFileLink("src/index.ts#L10-L20", { workspaceRoot: "/repo" }), + ).toMatchObject({ target: { path: "/repo/src/index.ts", lineStart: 10, lineEnd: 20 } }); +}); + +it("lets the engine own code boundaries while classifying candidate values", async () => { + const source = [ + "```ts\n`src/fenced.ts`\n```", + "`` src/app/[id].tsx `` and ` src/spaced.ts `", + "``src/a`b.ts`` and `src/after.ts`", + "\\`src/escaped.ts` and `src/final.ts`", + "`\nsrc/newline.ts\n`", + "[`src/explicit.ts`](https://example.com)", + ].join("\n\n"); + const prepared = prepareMarkdownSource(source, "/repo"); + const tree = recognizeTextLinks( + await parseMarkdown(prepared.render(), { latexMath: false }), + prepared.linkRecognition.text, + prepared.linkRecognition.inlineCode, + ); + const recognized: string[] = []; + function collect(node: ASTNode) { + if (node.type === "Link" && node.attributes?.recognizedLink === "true") { + recognized.push(String(node.attributes.url)); + } + node.children?.forEach(collect); + } + collect(tree); + expect(recognized).toEqual([ + "src/app/[id].tsx", + " src/spaced.ts ", + "src/a`b.ts", + "src/after.ts", + "src/escaped.ts", + "src/final.ts", + "src/newline.ts", + ]); +}); + +describe("bare URL sentence punctuation", () => { + it.each([".", ",", ";", ":", "!", "?", ")", ").", "...", "?!"])( + "leaves %s outside the link and preserves the rendered sentence", + async (punctuation) => { + const url = "https://github.com/getpaseo/paseo/pull/7357"; + const source = `${url}${punctuation} Not merged.`; + const prepared = prepareMarkdownSource(source); + const tree = recognizeTextLinks( + await parseMarkdown(prepared.render(), { latexMath: false }), + prepared.linkRecognition.text, + prepared.linkRecognition.inlineCode, + ); + expect(tree.children?.[0]?.children).toEqual([ + { + type: "Link", + attributes: { url }, + children: [{ type: "Text", content: url }], + }, + { type: "Text", content: `${punctuation} Not merged.` }, + ]); + }, + ); + + it.each([ + "https://example.com/a.b", + "https://example.com/a?foo=bar&baz=2", + "https://example.com/a#L10", + "https://en.wikipedia.org/wiki/Function_(mathematics)", + "https://example.com/a_(b_(c))", + ])("preserves internal URL punctuation: %s", async (url) => { + const tree = await parseMarkdown(prepareMarkdownSource(`${url}.`).render()); + expect(tree.children?.[0]?.children).toEqual([ + { + type: "Link", + attributes: { url }, + children: [{ type: "Text", content: url }], + }, + { type: "Text", content: "." }, + ]); + }); + + it.each(["[Authored](https://example.com/a.)", ""])( + "preserves punctuation in explicit destinations: %s", + async (source) => { + const tree = await parseMarkdown(prepareMarkdownSource(source).render()); + expect(tree.children?.[0]?.children?.[0]?.attributes?.url).toBe("https://example.com/a."); + }, + ); +}); + +it("requires workspace context for relative inline paths and escapes literal regex characters", () => { + const source = "`src/app/[id].tsx` and `src/a+b.ts` and `README.md` and `/tmp/file.ts`"; + const withoutWorkspace = prepareMarkdownSource(source).linkRecognition.inlineCode; + expect(withoutWorkspace.test("src/app/[id].tsx")).toBe(false); + expect(withoutWorkspace.test("README.md")).toBe(false); + expect(withoutWorkspace.test("/tmp/file.ts")).toBe(true); + const prepared = prepareMarkdownSource(source, "/repo"); + const native = toNativeLinkRecognition(prepared.linkRecognition); + const pattern = new RegExp(native.inlineCode.pattern); + expect(pattern.test("src/app/[id].tsx")).toBe(true); + expect(pattern.test("src/a+b.ts")).toBe(true); + expect(pattern.test("src/app/i.tsx")).toBe(false); + expect(pattern.test("src/ab.ts")).toBe(false); +}); + it("recognizes bare Unicode filenames and preserves inline-code URLs", () => { const prepared = prepareMarkdownSource("Read 说明.md, or `https://example.com`."); expect([..."说明.md,".matchAll(prepared.linkRecognition.text)].map(([text]) => text)).toEqual([ @@ -205,7 +357,7 @@ describe("shared Markdown theme colours", () => { ["dark", darkTheme], ["light", lightTheme], ] as const)("uses %s theme colours for tables and task labels", (_name, theme) => { - const { markdownStyle: style } = createMarkdownStyles(theme); + const { markdownStyle: style } = createMarkdownStyles(theme, { blockGap: 16 }); expect(style.table).toMatchObject({ color: theme.colors.foreground, headerTextColor: theme.colors.foreground, @@ -235,7 +387,7 @@ it.each([ ] as const)( "uses %s theme colours for quotes, admonitions, code, links and dividers", (_name, theme) => { - const { markdownStyle: style } = createMarkdownStyles(theme); + const { markdownStyle: style } = createMarkdownStyles(theme, { blockGap: 16 }); expect(style.blockquote).toMatchObject({ color: `${theme.colors.foreground}cc`, backgroundColor: theme.colors.surface1, @@ -262,7 +414,7 @@ it.each([ ); it.each([darkTheme, lightTheme])("supplies the theme selection colour to the renderer", (theme) => { - expect(createMarkdownStyles(theme)).toHaveProperty( + expect(createMarkdownStyles(theme, { blockGap: 16 })).toHaveProperty( "selectionColor", theme.colors.terminal.selectionBackground, ); @@ -329,7 +481,7 @@ it("preserves backslashes and decodes entities inside HTML code", () => { it.each([false, true])( "caps inline images to the paragraph line height (compact: %s)", (compact) => { - const { markdownStyle } = createMarkdownStyles(darkTheme, compact); + const { markdownStyle } = createMarkdownStyles(darkTheme, { compact, blockGap: 16 }); expect(markdownStyle.inlineImage?.size).toBe(markdownStyle.paragraph?.lineHeight); }, ); @@ -489,7 +641,7 @@ it.each([ "×/÷", "2024/10/16", ])("leaves non-path tokens unlinked in prose and inline code: %s", (token) => { - const { linkRecognition } = prepareMarkdownSource(`Value ${token}, then continue.`); + const { linkRecognition } = prepareMarkdownSource(`Value ${token}, then \`${token}\`.`, "/repo"); expect([...`Value ${token}, then continue.`.matchAll(linkRecognition.text)]).toEqual([]); expect(linkRecognition.inlineCode.test(token)).toBe(false); }); @@ -514,12 +666,11 @@ it.each([ "123.ts", "FILE.TS", "https://example.com/path", -])("recognizes complete paths and URLs in prose and inline code: %s", (token) => { - const { linkRecognition } = prepareMarkdownSource(`Open ${token} then continue.`); +])("recognizes complete paths and URLs in prose: %s", (token) => { + const { linkRecognition } = prepareMarkdownSource(`Open ${token} then \`${token}\`.`, "/repo"); expect( [...`Open ${token} then continue.`.matchAll(linkRecognition.text)].map(([text]) => text), ).toEqual([token]); - expect(linkRecognition.inlineCode.test(token)).toBe(true); }); it.each([ @@ -530,10 +681,13 @@ it.each([ "packages/app", "123/file", "src/123", -])("requires stronger path intent in prose while preserving inline code: %s", (token) => { - const { linkRecognition } = prepareMarkdownSource(`Compare ${token}, then continue.`); +])("leaves extensionless relative paths unlinked in prose and inline code: %s", (token) => { + const { linkRecognition } = prepareMarkdownSource( + `Compare ${token}, then \`${token}\`.`, + "/repo", + ); expect([...`Compare ${token}, then continue.`.matchAll(linkRecognition.text)]).toEqual([]); - expect(linkRecognition.inlineCode.test(token)).toBe(true); + expect(linkRecognition.inlineCode.test(token)).toBe(false); }); it("keeps prose and inline-code recognition enabled through the native regex adapter", () => { @@ -614,3 +768,10 @@ it("replaces the native placeholder only after the resolved URL decodes", () => const prepared = prepareMarkdownSource("![image](shot.png)", undefined, { supportsSvg: false }); expect(prepared.render(new Map([["shot.png", url]]))).toBe(`![image](<${url}>)`); }); + +it("makes the web Markdown container selectable in Safari as well as unprefixed browsers", () => { + expect(createMarkdownStyles(lightTheme, { blockGap: 12 }).containerStyle).toEqual({ + userSelect: "text", + WebkitUserSelect: "text", + }); +}); diff --git a/packages/app/src/components/markdown/renderer.tsx b/packages/app/src/components/markdown/renderer.tsx index c4a832342f..6d79beb01f 100644 --- a/packages/app/src/components/markdown/renderer.tsx +++ b/packages/app/src/components/markdown/renderer.tsx @@ -9,7 +9,8 @@ import { useStableEvent } from "@/hooks/use-stable-event"; import { AttachmentLightbox, type ImageLightboxSource } from "@/components/attachment-lightbox"; import type { Theme } from "@/styles/theme"; import { isWeb } from "@/constants/platform"; -import { MarkdownRendererFrame } from "./frame"; +import { density, resolveDensity } from "@/styles/density"; +import { MarkdownBlockStack } from "./block-stack"; import { WEB_RENDERERS } from "./renderers"; import { createMarkdownStyles } from "./styles"; import { PENDING_MARKDOWN_IMAGE } from "./source"; @@ -21,9 +22,11 @@ import { MermaidFence, MermaidStreamingContext, splitMermaidFences } from "./fen const ThemedMarkdown = withUnistyles(EnrichedMarkdownText); const MD4C_FLAGS = { latexMath: false, hardSoftBreaks: true, admonitions: true }; -const regularStyle = (theme: Theme) => createMarkdownStyles(theme); -const compactStyle = (theme: Theme) => createMarkdownStyles(theme, true); -const WEB_CONTAINER = { userSelect: "text" as const }; +// Reading the breakpoint here makes Unistyles restyle the text when the layout crosses it. +const markdownStyle = (compact: boolean) => (theme: Theme, rt: { breakpoint?: string }) => + createMarkdownStyles(theme, { compact, blockGap: resolveDensity(rt, density.blockGap) }); +const regularStyle = markdownStyle(false); +const compactStyle = markdownStyle(true); export interface MarkdownRendererProps extends MarkdownImageContext { text: string; @@ -43,21 +46,20 @@ export const MarkdownRenderer = memo(function MarkdownRenderer(props: MarkdownRe ); if (!streaming || boundary === 0) return ; return ( - <> - + + - + ); }); const MarkdownPart = memo(function MarkdownPart({ text, - continues = false, compact = false, streaming = false, onLinkPress, ...imageContext -}: MarkdownRendererProps & { continues?: boolean }) { +}: MarkdownRendererProps) { const environment = useAssistantFileLinkEnvironment(); const actions = useAssistantFileLinkActions(); const client = @@ -86,35 +88,34 @@ const MarkdownPart = memo(function MarkdownPart({ isWeb ? [{ kind: "markdown", id: "0", source: markdown }] : splitMermaidFences(markdown), [markdown], ); - const content = ( + return ( - {segments.map((segment) => - segment.kind === "mermaid" ? ( - - ) : ( - - ), - )} + + {segments.map((segment) => + segment.kind === "mermaid" ? ( + + ) : ( + + ), + )} + {image ? : null} ); - return {content}; }); diff --git a/packages/app/src/components/markdown/renderers.web.tsx b/packages/app/src/components/markdown/renderers.web.tsx index 6f0afc666b..1d05b3b603 100644 --- a/packages/app/src/components/markdown/renderers.web.tsx +++ b/packages/app/src/components/markdown/renderers.web.tsx @@ -1,5 +1,5 @@ import { Text } from "react-native"; -import { forwardRef, useMemo, type ComponentProps } from "react"; +import { forwardRef, useCallback, useMemo, useState, type ComponentProps } from "react"; import type { CodeBlockRendererProps, LinkRendererProps, @@ -27,14 +27,29 @@ function WebCodeBlock({ code, language }: CodeBlockRendererProps) { return ; } +// The library styles links inline, so a stylesheet :hover rule cannot underline them. +const LINK_HOVER_STYLE = { textDecoration: "underline" } as const; + function WebLink({ link, anchorProps, children }: LinkRendererProps) { const { tooltipPath, onHoverIn } = useFileLink(markdownLinkSource(link.url, link.sourceType)); + const [hovered, setHovered] = useState(false); + const handleMouseEnter = useCallback(() => setHovered(true), []); + const handleMouseLeave = useCallback(() => setHovered(false), []); const anchorStyle = useMemo( - () => ({ ...anchorProps.style, overflowWrap: "anywhere" as const }), - [anchorProps.style], + () => ({ + ...anchorProps.style, + overflowWrap: "anywhere" as const, + ...(hovered ? LINK_HOVER_STYLE : null), + }), + [anchorProps.style, hovered], ); const anchor = ( - + {children} ); diff --git a/packages/app/src/components/markdown/source.ts b/packages/app/src/components/markdown/source.ts index 9fda25b728..9977ccfef3 100644 --- a/packages/app/src/components/markdown/source.ts +++ b/packages/app/src/components/markdown/source.ts @@ -1,3 +1,4 @@ +import { classifyAssistantFileLink } from "@/assistant-file-links"; import { ASSISTANT_FILE_EXTENSIONS } from "@/assistant-file-links/extensions"; import { normalizeMarkdownHtml } from "./html"; import { gfmTable } from "micromark-extension-gfm-table"; @@ -22,7 +23,6 @@ const SEPARATED_PATH = String.raw`${PATH_SEGMENT}(?:[\\/]${PATH_SEGMENT})+`; const FILE_NAME = String.raw`${PATH_SEGMENT}\.(?:${FILE_EXTENSIONS})`; // Bare prose paths need a known extension, a line suffix, or at least two separators. const PROSE_PATH = String.raw`(?:${PATH_PREFIX}${HAS_PATH_LETTER}${SEPARATED_PATH}|${HAS_PATH_LETTER}(?:${PATH_SEGMENT}(?:[\\/]${PATH_SEGMENT})*[\\/]${FILE_NAME}|${PATH_SEGMENT}(?:[\\/]${PATH_SEGMENT}){2,}|${SEPARATED_PATH}(?=:)))`; -const INLINE_CODE_PATH = String.raw`${PATH_PREFIX}?${HAS_PATH_LETTER}${SEPARATED_PATH}`; function createFilePattern(path: string): RegExp { // The native adapter mistakes a literal + in lookbehind for a quantifier; use its hex escape. @@ -33,20 +33,46 @@ function createFilePattern(path: string): RegExp { } const FILE_PATTERN = createFilePattern(PROSE_PATH); -const INLINE_CODE_FILE_PATTERN = createFilePattern(INLINE_CODE_PATH); - -function linkMetadata() { +function linkMetadata(inlineCodePaths: ReadonlySet) { + // The engine accepts regexes on both platforms. Classify complete code spans + // first, then pass literal matches rather than maintaining a second path grammar. + const alternatives = [...inlineCodePaths].map((path) => + path.replace(/[.*+?^${}()|[\]\\]/g, "\\$&"), + ); return { linkRecognition: { text: FILE_PATTERN, inlineCode: new RegExp( - String.raw`^(?:${INLINE_CODE_FILE_PATTERN.source})(?:\(\d+(?:,\d+)?(?:-\d+(?:,\d+)?)?\)| lines? \d+(?:-\d+)?)?$`, + String.raw`^(?:https?://[^\s<>]+${alternatives.length ? `|${alternatives.join("|")}` : ""})$`, ), }, linkSource: markdownLinkSource, }; } +function collectInlineCodePaths(source: string, workspaceRoot?: string): ReadonlySet { + const paths = new Set(); + const previousEnds = new Map(); + // Collect candidates between consecutive runs of equal length. The engine owns + // Markdown context (escapes, fences, authored links); extra candidates are harmless + // because recognition only applies to complete Code nodes. This avoids an AST + // parse on every streaming reveal, including updates inside long code fences. + for (const match of source.matchAll(/`+/g)) { + const length = match[0].length; + const previousEnd = previousEnds.get(length); + previousEnds.set(length, match.index + length); + if (previousEnd === undefined) continue; + let value = source.slice(previousEnd, match.index).replace(/\r\n?|\n/g, " "); + // CommonMark code spans replace line endings and strip one surrounding space. + if (value.startsWith(" ") && value.endsWith(" ") && /[^ ]/.test(value)) { + value = value.slice(1, -1); + } + const classification = classifyAssistantFileLink(value, { workspaceRoot }); + if (classification && classification.kind !== "external") paths.add(value); + } + return paths; +} + export function markdownLinkSource( url: string, sourceType?: "markdown" | "text" | "inline-code", @@ -90,6 +116,7 @@ export function prepareMarkdownSource( extensions: [gfmTable()], mdastExtensions: [gfmTableFromMarkdown()], })); + const metadata = linkMetadata(collectInlineCodePaths(source, workspaceRoot)); const edits: { start: number; end: number; text: string }[] = []; if ( !source.includes("![") && @@ -97,7 +124,7 @@ export function prepareMarkdownSource( !source.includes("&") && !(workspaceRoot && source.includes("](")) ) { - return { images, ...linkMetadata(), render: () => source }; + return { images, ...metadata, render: () => source }; } const definitions = new Map(); @@ -206,7 +233,7 @@ export function prepareMarkdownSource( visit(getTree()); return { images, - ...linkMetadata(), + ...metadata, render( urls: ReadonlyMap = new Map(), unavailableImages: ReadonlySet = new Set(), diff --git a/packages/app/src/components/markdown/styles.ts b/packages/app/src/components/markdown/styles.ts index 03d6c69b23..faf388a9dc 100644 --- a/packages/app/src/components/markdown/styles.ts +++ b/packages/app/src/components/markdown/styles.ts @@ -2,27 +2,31 @@ import type { MarkdownStyle } from "react-native-enriched-markdown"; import type { Theme } from "@/styles/theme"; import { isWeb } from "@/constants/platform"; +// iOS Safari needs the prefix to override the gesture host's selection suppression. +const WEB_CONTAINER = { userSelect: "text", WebkitUserSelect: "text" } as const; + export function createMarkdownStyles( theme: Theme, - compact = false, -): { markdownStyle: MarkdownStyle; selectionColor: string } { + { compact = false, blockGap }: { compact?: boolean; blockGap: number }, +): { markdownStyle: MarkdownStyle; selectionColor: string; containerStyle?: typeof WEB_CONTAINER } { const fontSize = compact ? theme.fontSize.base : theme.fontSize.content; + // Every block is followed by the same gap; the library drops it after the last block. + const block = { marginTop: 0, marginBottom: blockGap }; const paragraph = { fontSize, fontFamily: theme.fontFamily.ui, lineHeight: Math.round(fontSize * 1.4), color: theme.colors.foreground, - marginTop: 0, - marginBottom: theme.spacing[3], + ...block, }; const heading = (scale: number) => ({ ...paragraph, fontSize: Math.round(fontSize * scale), lineHeight: Math.round(fontSize * scale * 1.3), fontWeight: "bold", - marginTop: theme.spacing[3], }); return { + containerStyle: isWeb ? WEB_CONTAINER : undefined, selectionColor: theme.colors.terminal.selectionBackground, markdownStyle: { paragraph, @@ -93,8 +97,8 @@ export function createMarkdownStyles( borderColor: theme.colors.foregroundMuted, }, inlineImage: { size: paragraph.lineHeight }, - image: { height: 320, resizeMode: "contain", borderRadius: 8 }, - thematicBreak: { color: theme.colors.border, height: 1, marginTop: 12, marginBottom: 12 }, + image: { ...block, height: 320, resizeMode: "contain", borderRadius: 8 }, + thematicBreak: { ...block, color: theme.colors.border, height: 1 }, }, }; } diff --git a/packages/app/src/components/message.tsx b/packages/app/src/components/message.tsx index 314f414d48..d5a2244505 100644 --- a/packages/app/src/components/message.tsx +++ b/packages/app/src/components/message.tsx @@ -26,6 +26,7 @@ import { writeMarkdownToRichClipboard } from "@/utils/rich-clipboard"; import { getDefaultMarkdownClipboardEnvironment } from "@/utils/rich-clipboard-default-environment"; import { formatDuration, formatMessageTimestamp } from "@/utils/time"; import { resolveToolCallIcon } from "@/utils/tool-call-icon"; +import { useTargetAgentTitle } from "@/tool-calls/use-target-agent-title"; import type { DaemonClient } from "@getpaseo/client/internal/daemon-client"; import type { AgentMessage } from "@getpaseo/protocol/agent-message"; import type { AgentCapabilityFlags, ToolCallDetail } from "@getpaseo/protocol/agent-types"; @@ -2208,6 +2209,7 @@ function areExpandableBadgePropsEqual(previous: ExpandableBadgeProps, next: Expa interface ToolCallProps { agentMessage?: AgentMessage; + serverId?: string; toolName: string; args?: unknown; result?: unknown; @@ -2228,6 +2230,7 @@ interface ToolCallProps { export const ToolCall = memo(function ToolCall({ agentMessage, + serverId, toolName, args, result, @@ -2265,6 +2268,7 @@ export const ToolCall = memo(function ToolCall({ return undefined; }, [detail, args, result]); + const targetAgentTitle = useTargetAgentTitle({ serverId, toolName, detail: effectiveDetail }); const presentation = useMemo( () => buildToolCallPresentation({ @@ -2275,9 +2279,10 @@ export const ToolCall = memo(function ToolCall({ detail: effectiveDetail, metadata, cwd, + targetAgentTitle, resolveIcon: resolveToolCallIcon, }), - [toolName, status, error, effectiveDetail, metadata, cwd, agentMessage], + [toolName, status, error, effectiveDetail, metadata, cwd, agentMessage, targetAgentTitle], ); const handleOpenFile = useMemo(() => { const openFilePath = presentation.openFilePath; @@ -2393,6 +2398,8 @@ export const ToolCall = memo(function ToolCall({ function areToolCallPropsEqual(previous: ToolCallProps, next: ToolCallProps) { if (previous.toolName !== next.toolName) return false; + if (previous.serverId !== next.serverId) return false; + if (previous.agentMessage !== next.agentMessage) return false; if (previous.args !== next.args) return false; if (previous.result !== next.result) return false; if (previous.error !== next.error) return false; diff --git a/packages/app/src/components/page-layout/index.tsx b/packages/app/src/components/page-layout/index.tsx index e0c46b695a..4f3bb57af4 100644 --- a/packages/app/src/components/page-layout/index.tsx +++ b/packages/app/src/components/page-layout/index.tsx @@ -1,10 +1,14 @@ import { useMemo, type ReactNode } from "react"; -import { ScrollView, Text, View } from "react-native"; +import { Platform, ScrollView, Text, View } from "react-native"; +import { KeyboardAwareScrollView } from "react-native-keyboard-controller"; import { useSafeAreaInsets } from "react-native-safe-area-context"; import { StyleSheet } from "react-native-unistyles"; import { BackHeader } from "@/components/headers/back-header"; import { MenuHeader } from "@/components/headers/menu-header"; import { useIsCompactFormFactor } from "@/constants/layout"; +import { SPACING } from "@/styles/theme"; + +const PageScrollView = Platform.OS === "android" ? KeyboardAwareScrollView : ScrollView; interface PageLayoutProps { title?: string; @@ -42,7 +46,13 @@ export function PageLayout({ ) : ( )} - + {showTitle ? ( @@ -54,7 +64,7 @@ export function PageLayout({ ) : null} {children} - + ); } diff --git a/packages/app/src/components/provider-icon-name.test.ts b/packages/app/src/components/provider-icon-name.test.ts index 65c75166a5..0083926627 100644 --- a/packages/app/src/components/provider-icon-name.test.ts +++ b/packages/app/src/components/provider-icon-name.test.ts @@ -17,8 +17,10 @@ describe("resolveProviderIconName", () => { it("returns the catalog identifier for ACP catalog provider ids that ship an icon", () => { expect(resolveProviderIconName("amp-acp")).toEqual({ kind: "catalog", id: "amp-acp" }); + expect(resolveProviderIconName("devin")).toEqual({ kind: "catalog", id: "devin" }); expect(resolveProviderIconName("gemini")).toEqual({ kind: "catalog", id: "gemini" }); expect(resolveProviderIconName("gjc")).toEqual({ kind: "catalog", id: "gjc" }); + expect(resolveProviderIconName("hermes")).toEqual({ kind: "catalog", id: "hermes" }); expect(resolveProviderIconName("traecli")).toEqual({ kind: "catalog", id: "traecli" }); }); diff --git a/packages/app/src/components/provider-icons.test.ts b/packages/app/src/components/provider-icons.test.ts index 025ff14bef..aceed473be 100644 --- a/packages/app/src/components/provider-icons.test.ts +++ b/packages/app/src/components/provider-icons.test.ts @@ -1,6 +1,6 @@ // @vitest-environment jsdom import { act, cleanup, renderHook } from "@testing-library/react"; -import { Bot } from "lucide-react-native"; +import { Bot, PackagePlus } from "lucide-react-native"; import { SvgXml } from "react-native-svg"; import { afterEach, describe, expect, it } from "vitest"; import { replaceProviderSnapshotIcons } from "@/data/provider-icons"; @@ -17,6 +17,16 @@ function renderIcon(Component: ProviderIconComponent) { } describe("useProviderIcon", () => { + it.each(["devin", "hermes", "kiro", "antigravity"])( + "#7087: %s has a provider mark before a host snapshot arrives", + (provider) => { + const Icon = renderHook(() => useProviderIcon(provider)).result.current; + expect(Icon).not.toBe(Bot); + expect(Icon).not.toBe(PackagePlus); + expect(typeof Icon).toBe("function"); + }, + ); + it("renders registered snapshot SVG metadata with the requested size and color", () => { const svg = ''; replaceProviderSnapshotIcons("server-1", [{ provider: "rendered-provider", iconSvg: svg }]); diff --git a/packages/app/src/components/provider-icons.ts b/packages/app/src/components/provider-icons.ts index 883b4820f7..d8548cbd16 100644 --- a/packages/app/src/components/provider-icons.ts +++ b/packages/app/src/components/provider-icons.ts @@ -1,12 +1,14 @@ import { useStore } from "zustand"; import { providerSnapshotIcons } from "@/data/provider-icons"; -import { Bot, PackagePlus } from "lucide-react-native"; +import { Bot } from "lucide-react-native"; import { createElement, useCallback, type ComponentType } from "react"; import { SvgXml } from "react-native-svg"; import { TERMINAL_PROFILE_ICON_NAMES } from "@getpaseo/protocol/provider-icon-names"; +import { AntigravityIcon } from "@/components/icons/antigravity-icon"; import { ClaudeIcon } from "@/components/icons/claude-icon"; import { CodexIcon } from "@/components/icons/codex-icon"; import { CopilotIcon } from "@/components/icons/copilot-icon"; +import { KiroIcon } from "@/components/icons/kiro-icon"; import { MiniMaxIcon } from "@/components/icons/minimax-icon"; import { OpenCodeIcon } from "@/components/icons/opencode-icon"; import { OmpIcon } from "@/components/icons/omp-icon"; @@ -23,10 +25,11 @@ export interface ProviderIconProps { export type ProviderIconComponent = ComponentType; const BUILTIN_PROVIDER_ICONS: Record = { + antigravity: AntigravityIcon as unknown as ProviderIconComponent, claude: ClaudeIcon as unknown as ProviderIconComponent, codex: CodexIcon as unknown as ProviderIconComponent, copilot: CopilotIcon as unknown as ProviderIconComponent, - kiro: PackagePlus, + kiro: KiroIcon as unknown as ProviderIconComponent, minimax: MiniMaxIcon as unknown as ProviderIconComponent, omp: OmpIcon as unknown as ProviderIconComponent, opencode: OpenCodeIcon as unknown as ProviderIconComponent, diff --git a/packages/app/src/components/sidebar-workspace-list.tsx b/packages/app/src/components/sidebar-workspace-list.tsx index c750121368..9ce91b5a10 100644 --- a/packages/app/src/components/sidebar-workspace-list.tsx +++ b/packages/app/src/components/sidebar-workspace-list.tsx @@ -41,7 +41,11 @@ import { ExternalLink, Settings, MoreVertical, Plus, Trash2 } from "lucide-react import { NestableScrollContainer } from "react-native-draggable-flatlist"; import { DraggableList, type DraggableRenderItemInfo } from "./draggable-list"; import type { DraggableListDragHandleProps } from "./draggable-list.types"; -import { getHostRuntimeStore, useHosts } from "@/runtime/host-runtime"; +import { + getHostRuntimeStore, + useHosts, + useHostRuntimeConnectionStatus, +} from "@/runtime/host-runtime"; import type { PinnedSidebarGroups } from "@/hooks/use-sidebar-pins"; import { useSidebarWorkspacePinController, @@ -1596,14 +1600,18 @@ function ProjectBlock({ canToggle: canToggleWorkspaces, toggleExpanded: toggleWorkspacesExpanded, } = useLimitedSidebarGroup(project.workspaces); + const activeServerId = activeWorkspaceSelection?.serverId ?? null; + const activeHostStatus = useHostRuntimeConnectionStatus(activeServerId ?? ""); + const preferredServerId = activeHostStatus === "online" ? activeServerId : null; const rowModel = useMemo( () => buildSidebarProjectRowModel({ project, collapsed, supportsMultiplicityByServerId, + preferredServerId, }), - [collapsed, project, supportsMultiplicityByServerId], + [collapsed, preferredServerId, project, supportsMultiplicityByServerId], ); // Collapsed rows hide their workspace rows, so the project row carries the most urgent @@ -1848,6 +1856,7 @@ function areProjectBlockPropsEqual(previous: ProjectBlockProps, next: ProjectBlo previous.useNestable === next.useNestable && previous.dragGestureHostActive === next.dragGestureHostActive && previous.creatingWorkspaceIds === next.creatingWorkspaceIds && + previous.activeWorkspaceSelection?.serverId === next.activeWorkspaceSelection?.serverId && areProjectBlockSelectionsEqual(previous, next) ); } diff --git a/packages/app/src/components/sidebar/empty-states.browser.test.tsx b/packages/app/src/components/sidebar/empty-states.browser.test.tsx new file mode 100644 index 0000000000..85cd96c0e6 --- /dev/null +++ b/packages/app/src/components/sidebar/empty-states.browser.test.tsx @@ -0,0 +1,85 @@ +import React, { act } from "react"; +import { createRoot, type Root } from "react-dom/client"; +import { afterEach, beforeEach, describe, expect, it, vi } from "vitest"; +import { getAllByRole } from "@testing-library/dom"; +import { i18n as testI18n } from "@/i18n/i18next"; +import { DEFAULT_SIDEBAR_WIDTH, MIN_SIDEBAR_WIDTH } from "@/stores/panel-store"; +import { SidebarProjectEmptyState } from "./empty-states"; + +// App sources compile against the classic JSX runtime, which expects React on the global. +beforeEach(() => vi.stubGlobal("React", React)); + +interface Mounted { + root: Root; + container: HTMLDivElement; +} + +const mounted: Mounted[] = []; + +afterEach(async () => { + for (const entry of mounted.splice(0)) { + act(() => entry.root.unmount()); + entry.container.remove(); + } + await testI18n.changeLanguage("en"); +}); + +async function mountEmptyState(language: string, width: number): Promise { + await testI18n.changeLanguage(language); + + const container = document.createElement("div"); + container.style.width = `${width}px`; + // Match the workspace list's horizontal inset around the card. + container.style.paddingInline = "6px"; + container.style.boxSizing = "border-box"; + document.body.appendChild(container); + const root = createRoot(container); + act(() => root.render()); + mounted.push({ root, container }); + + const card = container.querySelector('[data-testid="sidebar-project-empty-state"]'); + if (!(card instanceof HTMLElement)) { + throw new Error("SidebarProjectEmptyState did not render its card"); + } + return card; +} + +function expectActionsInsideCard(card: HTMLElement) { + const cardRect = card.getBoundingClientRect(); + const buttons = getAllByRole(card, "button"); + + expect(buttons).toHaveLength(2); + for (const button of buttons) { + const rect = button.getBoundingClientRect(); + expect(rect.left).toBeGreaterThanOrEqual(cardRect.left); + expect(rect.right).toBeLessThanOrEqual(cardRect.right); + + // Containing the button must also keep the whole label readable, without clipping. + const label = document.createRange(); + label.selectNodeContents(button); + for (const fragment of Array.from(label.getClientRects())) { + expect(fragment.left).toBeGreaterThanOrEqual(rect.left); + expect(fragment.right).toBeLessThanOrEqual(rect.right); + expect(fragment.top).toBeGreaterThanOrEqual(rect.top); + expect(fragment.bottom).toBeLessThanOrEqual(rect.bottom); + } + } +} + +describe("SidebarProjectEmptyState", () => { + const cases = ["en", "ru", "fr", "ja", "es", "pt-BR", "ar", "ko", "zh-CN"].flatMap((language) => + [MIN_SIDEBAR_WIDTH, DEFAULT_SIDEBAR_WIDTH].map((width) => ({ language, width })), + ); + it.each(cases)( + "keeps every action inside the card ($language, $width px sidebar)", + async ({ language, width }) => { + expectActionsInsideCard(await mountEmptyState(language, width)); + }, + ); + + it("keeps English actions on one row when they fit", async () => { + const card = await mountEmptyState("en", DEFAULT_SIDEBAR_WIDTH); + const [addProject, importSession] = getAllByRole(card, "button"); + expect(addProject.getBoundingClientRect().top).toBe(importSession.getBoundingClientRect().top); + }); +}); diff --git a/packages/app/src/components/sidebar/empty-states.tsx b/packages/app/src/components/sidebar/empty-states.tsx index 3328ed2c5c..c9f6b7c568 100644 --- a/packages/app/src/components/sidebar/empty-states.tsx +++ b/packages/app/src/components/sidebar/empty-states.tsx @@ -54,7 +54,13 @@ export function SidebarFilterEmptyState() { title={t("sidebar.filterEmpty.title")} description={t("sidebar.filterEmpty.description")} > - @@ -76,10 +82,24 @@ export function SidebarProjectEmptyState({ title={t("sidebar.project.empty.title")} description={t("sidebar.project.empty.description")} > - - @@ -99,9 +119,16 @@ const styles = StyleSheet.create((theme) => ({ }, actions: { flexDirection: "row", + flexWrap: "wrap", gap: theme.spacing[2], marginTop: theme.spacing[4], }, + action: { + maxWidth: "100%", + }, + actionText: { + flexShrink: 1, + }, title: { color: theme.colors.foreground, fontSize: theme.fontSize.sm, diff --git a/packages/app/src/components/split-container.tsx b/packages/app/src/components/split-container.tsx index 9705f3be15..c6d95f40b7 100644 --- a/packages/app/src/components/split-container.tsx +++ b/packages/app/src/components/split-container.tsx @@ -1,5 +1,6 @@ import { Fragment, + memo, useCallback, useEffect, useMemo, @@ -88,7 +89,8 @@ import { type WorkspaceLayout, } from "@/stores/workspace-layout-store"; import type { WorkspaceTab } from "@/workspace-tabs/model"; -import { RenderProfile } from "@/utils/render-profiler"; +import { recordRenderProfileReasons, RenderProfile } from "@/utils/render-profiler"; +import { inlineUnistylesStyle } from "@/styles/unistyles-inline-style"; import { isNative } from "@/constants/platform"; import { panelTargetSupportsHost } from "@/plugins/workspace-panels/locations"; @@ -435,7 +437,7 @@ export function SplitContainer({ : inheritedWindowChromeCorners; const mainColumnStyle = styles.mainColumn; const explorerSidebarDockStyle = useMemo( - () => [styles.explorerSidebarDock, { width: explorerSidebarWidth }], + () => [styles.explorerSidebarDock, inlineUnistylesStyle({ width: explorerSidebarWidth })], [explorerSidebarWidth], ); const handleWorkspaceShellLayout = useCallback((event: LayoutChangeEvent) => { @@ -1121,7 +1123,7 @@ function SplitNodeView({ ); } -function SplitPaneView({ +const SplitPaneView = memo(function SplitPaneView({ pane, uiTabs, isFocused, @@ -1158,6 +1160,7 @@ function SplitPaneView({ focusModeEnabled, onExitFocusMode, }: SplitPaneViewProps) { + recordRenderProfileReasons(`SplitPaneView:${pane.id}`, ["render"]); const paneRef = useRef(null); const stableOnFocusPane = useStableEvent(onFocusPane); const paneState = useMemo( @@ -1312,7 +1315,7 @@ function SplitPaneView({ ); -} +}); function collectPanesById(node: SplitNode): Map { const next = new Map(); diff --git a/packages/app/src/components/terminal-emulator-native-grid.native.tsx b/packages/app/src/components/terminal-emulator-native-grid.native.tsx index 311528bdac..dcda257116 100644 --- a/packages/app/src/components/terminal-emulator-native-grid.native.tsx +++ b/packages/app/src/components/terminal-emulator-native-grid.native.tsx @@ -868,7 +868,9 @@ function NativeTerminalEmulator({ panState.movedBeyondTapTolerance = true; } if (selectionPress?.status === "selecting") { - updateSelectionAtPoint(resolvePanResponderPoint(selectionPress, event, gesture)); + if (panState.movedBeyondTapTolerance) { + updateSelectionAtPoint(resolvePanResponderPoint(selectionPress, event, gesture)); + } return; } @@ -915,7 +917,10 @@ function NativeTerminalEmulator({ onPanResponderRelease: (event, gesture) => { clearSelectionLongPressTimeout(); const selectionPress = selectionPressRef.current; - if (selectionPress?.status === "selecting") { + if ( + selectionPress?.status === "selecting" && + panStateRef.current.movedBeyondTapTolerance + ) { updateSelectionAtPoint(resolvePanResponderPoint(selectionPress, event, gesture)); } selectionPressRef.current = null; diff --git a/packages/app/src/components/tool-call-details.tsx b/packages/app/src/components/tool-call-details.tsx index 50e4052118..d67eb15f26 100644 --- a/packages/app/src/components/tool-call-details.tsx +++ b/packages/app/src/components/tool-call-details.tsx @@ -14,7 +14,7 @@ import type { ToolCallDetail } from "@getpaseo/protocol/agent-types"; import { buildPaseoToolDetailSections, type PaseoToolDetailSection, -} from "@getpaseo/protocol/paseo-tool-call-detail"; +} from "@getpaseo/protocol/paseo-tool-presentation/index"; import { buildLineDiff, parseUnifiedDiff, type DiffLine } from "@/utils/tool-call-parsers"; import { highlightDiffLines } from "@/utils/diff-highlight"; import { hasMeaningfulToolCallDetail } from "@/utils/tool-call-detail-state"; diff --git a/packages/app/src/components/ui/highlighted-text-segments.test.ts b/packages/app/src/components/ui/highlighted-text-segments.test.ts index 6f42fe823d..4e23389fde 100644 --- a/packages/app/src/components/ui/highlighted-text-segments.test.ts +++ b/packages/app/src/components/ui/highlighted-text-segments.test.ts @@ -63,7 +63,9 @@ describe("findHighlightRanges", () => { ); }); it("uses the search matcher for typo and scattered-character matches", () => { - expect(marked("billing", findHighlightRanges("bulling", "billing"))).toBe("[billing]"); + expect( + marked("billing", findHighlightRanges("bulling", "billing", { typoTolerant: true })), + ).toBe("[billing]"); expect(marked("paseo-babysit", findHighlightRanges("pasbab", "paseo-babysit"))).toBe( "[pas]eo-[bab]ysit", ); @@ -79,6 +81,9 @@ describe("findHighlightRanges", () => { "check [conf]i[g]uration", ); }); + it("marks typos only when the list was matched typo-tolerantly", () => { + expect(findHighlightRanges("bulling", "billing")).toEqual([]); + }); it("merges overlapping tokens and ignores empty or unmatched queries", () => { expect(marked("billing", findHighlightRanges("bill billing", "billing"))).toBe("[billing]"); expect(findHighlightRanges("", "billing")).toEqual([]); diff --git a/packages/app/src/components/ui/highlighted-text-segments.ts b/packages/app/src/components/ui/highlighted-text-segments.ts index 0bd4f1e0bd..f65f6c44eb 100644 --- a/packages/app/src/components/ui/highlighted-text-segments.ts +++ b/packages/app/src/components/ui/highlighted-text-segments.ts @@ -4,6 +4,7 @@ import { scoreMatch, tokenizeQuery, type MatchRange, + type TextFieldsOptions, } from "@getpaseo/protocol/search/text-match"; export interface HighlightSegment { @@ -40,11 +41,22 @@ export function toHighlightSegments( return segments; } -/** Best-effort presentation of each query token in this field, independently of other fields. */ -export function findHighlightRanges(query: string, text: string): MatchRange[] { +/** + * Best-effort presentation of each query token in this field, independently of other fields. + * Pass the same options the list was matched with, so a mark never claims a match the list did + * not make. + */ +export function findHighlightRanges( + query: string, + text: string, + options: TextFieldsOptions = {}, +): MatchRange[] { const ranges = tokenizeQuery(query) .flatMap((token) => { - const score = scoreMatch(token, text, { fuzzy: fuzzyPolicyForToken(token) }); + const score = scoreMatch(token, text, { + fuzzy: options.typoTolerant ? fuzzyPolicyForToken(token) : null, + subsequence: options.subsequence, + }); return score ? matchRanges(token, text, score) : []; }) .sort((left, right) => left.start - right.start); diff --git a/packages/app/src/composer/draft/workspace-tab-core.ts b/packages/app/src/composer/draft/workspace-tab-core.ts index 30411aeb00..26bf548064 100644 --- a/packages/app/src/composer/draft/workspace-tab-core.ts +++ b/packages/app/src/composer/draft/workspace-tab-core.ts @@ -24,7 +24,7 @@ export function validateDraftSubmission(input: { }; autoSubmitConfig: WorkspaceDraftAutoSubmitConfig | null; workspaceDirectory: string | null; - hasClient: boolean; + isConnected: boolean; }): string | null { const { text, @@ -32,7 +32,7 @@ export function validateDraftSubmission(input: { composerState, autoSubmitConfig, workspaceDirectory, - hasClient, + isConnected, } = input; const readiness = resolveSubmissionReadiness({ text, @@ -46,7 +46,7 @@ export function validateDraftSubmission(input: { }, autoSubmitConfig, workspaceDirectory, - hasClient, + isConnected, }); return readiness.ok ? null : (readiness.reason ?? null); } diff --git a/packages/app/src/composer/draft/workspace-tab.test.ts b/packages/app/src/composer/draft/workspace-tab.test.ts index 5952083a62..1d7e2d4b2c 100644 --- a/packages/app/src/composer/draft/workspace-tab.test.ts +++ b/packages/app/src/composer/draft/workspace-tab.test.ts @@ -17,12 +17,26 @@ function validate(overrides = {}) { composerState: baseComposerState, autoSubmitConfig: null, workspaceDirectory: "/tmp/project", - hasClient: true, + isConnected: true, ...overrides, }); } describe("workspace draft agent model validation", () => { + test("reports an offline host before an absent catalog or pending model defaults", () => { + expect( + validate({ + isConnected: false, + composerState: { + ...baseComposerState, + providerDefinitions: [], + selectedProvider: null, + isModelLoading: true, + }, + }), + ).toBe("Host is not connected"); + }); + test("allows a ready provider with no models to submit without a selected model", () => { expect(validate({})).toBeNull(); }); diff --git a/packages/app/src/composer/draft/workspace-tab.tsx b/packages/app/src/composer/draft/workspace-tab.tsx index b54b344a36..27ca8b8af8 100644 --- a/packages/app/src/composer/draft/workspace-tab.tsx +++ b/packages/app/src/composer/draft/workspace-tab.tsx @@ -16,7 +16,7 @@ import { useAgentInputDraft } from "@/composer/draft/input-draft"; import type { CreateAgentInitialValues } from "@/hooks/use-agent-form-state"; import { useDraftAgentCreateFlow, type DraftCreateAttempt } from "@/composer/draft/create-flow"; import { resolveTurnPresentation, TURN_LIVENESS_IDLE } from "@/timeline/turn-liveness"; -import { useHostRuntimeClient } from "@/runtime/host-runtime"; +import { useHostRuntimeClient, useHostRuntimeIsConnected } from "@/runtime/host-runtime"; import { buildWorkspaceDraftAgentConfig } from "@/screens/workspace/workspace-draft-agent-config"; import { buildDraftStoreKey } from "@/stores/draft-keys"; import { useCreateFlowStore } from "@/stores/create-flow-store"; @@ -305,6 +305,7 @@ export function WorkspaceDraftAgentTab({ }: WorkspaceDraftAgentTabProps) { const { t } = useTranslation(); const client = useHostRuntimeClient(serverId); + const isConnected = useHostRuntimeIsConnected(serverId); const workspaceFields = useWorkspaceFields(serverId, workspaceId, (w) => ({ workspaceDirectory: w.workspaceDirectory, id: w.id, @@ -445,7 +446,7 @@ export function WorkspaceDraftAgentTab({ composerState, autoSubmitConfig, workspaceDirectory: draftWorkingDirectory, - hasClient: Boolean(client), + isConnected, }); }, onBeforeSubmit: async () => { diff --git a/packages/app/src/composer/input/input.tsx b/packages/app/src/composer/input/input.tsx index 9fdab3fa28..2c104924cc 100644 --- a/packages/app/src/composer/input/input.tsx +++ b/packages/app/src/composer/input/input.tsx @@ -1295,7 +1295,12 @@ export const MessageInput = forwardRef( // Read pointer capability when restoring, without making a pointer change itself // a focus trigger. useLayoutEffect(() => { - if (isPaneFocused && focusIntentRef.current && hasFinePointer()) { + const finePointer = hasFinePointer(); + if (!isPaneFocused && isWeb && !finePointer) { + // Hiding a retained tab only blurs its editor after the browser renders. + // A quick return before that frame would otherwise keep touch focus. + textInputRef.current?.blur(); + } else if (isPaneFocused && focusIntentRef.current && finePointer) { textInputRef.current?.focus(); } }, [isPaneFocused]); diff --git a/packages/app/src/composer/submission/model.test.ts b/packages/app/src/composer/submission/model.test.ts index 147ccce954..3aea318f4f 100644 --- a/packages/app/src/composer/submission/model.test.ts +++ b/packages/app/src/composer/submission/model.test.ts @@ -4,6 +4,7 @@ import { beginMessageSubmission, getActiveMessageSubmissions, getSendingClientMessageIds, + hasActiveMessageSubmission, observeMessageSubmissionCanonical, rejectMessageSubmission, } from "./model"; @@ -53,6 +54,21 @@ describe("message submission transactions", () => { expect(observeMessageSubmissionCanonical(accepted, ["client-1"])).toEqual([]); }); + it("reports activity until every submission is provider acknowledged", () => { + const both = beginMessageSubmission( + beginMessageSubmission([], { clientMessageId: "client-1" }), + { clientMessageId: "client-2" }, + ); + const oneAcknowledged = observeMessageSubmissionCanonical(both, ["client-1"]); + + expect(hasActiveMessageSubmission(undefined)).toBe(false); + expect(hasActiveMessageSubmission(both)).toBe(true); + expect(hasActiveMessageSubmission(oneAcknowledged)).toBe(true); + expect( + hasActiveMessageSubmission(observeMessageSubmissionCanonical(oneAcknowledged, ["client-2"])), + ).toBe(false); + }); + it("records provider acknowledgement without settling another transaction", () => { const both = beginMessageSubmission( beginMessageSubmission([], { clientMessageId: "client-1" }), diff --git a/packages/app/src/composer/tracks.tsx b/packages/app/src/composer/tracks.tsx index e33cd6ba53..3a4541d285 100644 --- a/packages/app/src/composer/tracks.tsx +++ b/packages/app/src/composer/tracks.tsx @@ -2,6 +2,7 @@ import { useCallback, useMemo, useState, type ReactElement, type ReactNode } fro import { Pressable, Text, View } from "react-native"; import { StyleSheet } from "react-native-unistyles"; import { + MENU_ITEM_HEIGHT, MenuRoot, MenuSeparator, MenuSurface, @@ -312,6 +313,22 @@ const styles = StyleSheet.create((theme) => { backgroundColor: getStatusDotColor({ theme, bucket, showDoneAsInactive: true }) ?? undefined, }); + // The rail every panel row sits on: inset from the panel edge so the fill is a rounded block + // inside it, and tall enough that revealing an action button cannot resize the row. + // + // Compact and desktop differ here and only here. A finger needs the taller row a menu row gets + // on compact; a pointer does not, and the popover keeps its density. + const trackRow = { + flexDirection: "row", + alignItems: "center", + gap: theme.spacing[2], + minHeight: { xs: MENU_ITEM_HEIGHT.xs, md: 32 }, + marginHorizontal: theme.spacing[1], + paddingHorizontal: theme.spacing[2], + paddingVertical: { xs: theme.spacing[2], md: theme.spacing[1] }, + borderRadius: theme.borderRadius.md, + } as const; + return { bar: { position: "absolute", @@ -332,29 +349,8 @@ const styles = StyleSheet.create((theme) => { alignItems: "center", gap: theme.spacing[1], }, - // The rail every panel row sits on: inset from the panel edge so the fill is a rounded block - // inside it, and tall enough that revealing an action button cannot resize the row. - row: { - flexDirection: "row", - alignItems: "center", - gap: theme.spacing[2], - minHeight: 32, - marginHorizontal: theme.spacing[1], - paddingHorizontal: theme.spacing[2], - paddingVertical: theme.spacing[1], - borderRadius: theme.borderRadius.md, - }, - rowActive: { - flexDirection: "row", - alignItems: "center", - gap: theme.spacing[2], - minHeight: 32, - marginHorizontal: theme.spacing[1], - paddingHorizontal: theme.spacing[2], - paddingVertical: theme.spacing[1], - borderRadius: theme.borderRadius.md, - backgroundColor: theme.colors.surface2, - }, + row: trackRow, + rowActive: { ...trackRow, backgroundColor: theme.colors.surface2 }, // Segments sit twice as far apart as a mark sits from its own text, so a count reads as // belonging to the mark on its left rather than to the words on its right. segments: { diff --git a/packages/app/src/contexts/session-context.tsx b/packages/app/src/contexts/session-context.tsx index 430e4ade74..7190b42462 100644 --- a/packages/app/src/contexts/session-context.tsx +++ b/packages/app/src/contexts/session-context.tsx @@ -36,7 +36,6 @@ import { useSessionStore, type SessionState, } from "@/stores/session-store"; -import { useWorkspaceSetupStore } from "@/stores/workspace-setup-store"; import { sendOsNotification } from "@/utils/os-notifications"; import { getIsAppActivelyVisible, getIsAppVisible } from "@/utils/app-visibility"; import { @@ -168,11 +167,6 @@ function resolveAgentAttentionNotification( }); } -type WorkspaceSetupProgressPayload = Extract< - SessionOutboundMessage, - { type: "workspace_setup_progress" } ->["payload"]; - function notifyVoiceAbortFailure( data: Extract["payload"], notifyError: (message: string) => void, @@ -225,7 +219,6 @@ function SessionProviderInternal({ children, serverId, client }: SessionProvider const setPendingPermissions = useSessionStore((state) => state.setPendingPermissions); const updateSessionServerInfo = useSessionStore((state) => state.updateSessionServerInfo); const setViewedTimelineSync = useSessionStore((state) => state.setViewedTimelineSync); - const upsertWorkspaceSetupProgress = useWorkspaceSetupStore((state) => state.upsertProgress); // Track focused agent for heartbeat const focusedAgentId = useSessionStore( @@ -365,13 +358,6 @@ function SessionProviderInternal({ children, serverId, client }: SessionProvider } }, [flushAgentLastActivity, serverId, isConnected, setInitializingAgents]); - const applyWorkspaceSetupProgress = useCallback( - (payload: WorkspaceSetupProgressPayload) => { - upsertWorkspaceSetupProgress({ serverId, payload }); - }, - [serverId, upsertWorkspaceSetupProgress], - ); - useEffect(() => { const setAgentInitializing = createSetAgentInitializing(serverId, setInitializingAgents); const onStream = (message: SessionOutboundMessage) => { @@ -508,7 +494,6 @@ function SessionProviderInternal({ children, serverId, client }: SessionProvider "agent_permission_resolved", "agent.provider_subagents.update", "checkout_status_update", - "workspace_setup_progress", "status.server_info", ], { notifications: true }, @@ -547,11 +532,6 @@ function SessionProviderInternal({ children, serverId, client }: SessionProvider applyCheckoutStatusUpdateFromEvent({ queryClient, serverId, message }); }); - const unsubWorkspaceSetupProgress = onFeed("workspace_setup_progress", (message) => { - if (message.type !== "workspace_setup_progress") return; - applyWorkspaceSetupProgress(message.payload); - }); - const unsubStatus = onFeed("status", (message) => { if (message.type !== "status") return; const serverInfo = parseServerInfoStatusPayload(message.payload); @@ -710,7 +690,6 @@ function SessionProviderInternal({ children, serverId, client }: SessionProvider unsubProviderSubagentUpdate(); unsubAgentAttention(); unsubCheckoutStatusUpdate(); - unsubWorkspaceSetupProgress(); unsubStatus(); unsubPermissionRequest(); unsubPermissionResolved(); @@ -732,7 +711,6 @@ function SessionProviderInternal({ children, serverId, client }: SessionProvider setAgents, setPendingPermissions, notifyAgentAttention, - applyWorkspaceSetupProgress, updateSessionServerInfo, toast, voiceRuntime, diff --git a/packages/app/src/data/acp-provider-catalog.ts b/packages/app/src/data/acp-provider-catalog.ts index 1bd32db53d..f91a9540f2 100644 --- a/packages/app/src/data/acp-provider-catalog.ts +++ b/packages/app/src/data/acp-provider-catalog.ts @@ -133,7 +133,7 @@ const CATALOG_DATA = [ title: "Devin CLI", description: "Cognition's Devin for Terminal via Agent Client Protocol", version: "manual", - iconId: null, + iconId: "devin", installLink: "https://cli.devin.ai/docs", command: ["devin", "acp"], }, @@ -235,7 +235,7 @@ const CATALOG_DATA = [ title: "Hermes", description: "Nous Research self-improving AI agent", version: "manual", - iconId: null, + iconId: "hermes", installLink: "https://hermes-agent.nousresearch.com/docs/user-guide/features/acp", command: ["hermes", "acp"], }, @@ -272,7 +272,7 @@ const CATALOG_DATA = [ title: "Kiro CLI", description: "Amazon's AI coding agent with native ACP support", version: "manual", - iconId: null, + iconId: "kiro", installLink: "https://kiro.dev/docs/cli/acp/", command: ["kiro-cli", "acp"], }, diff --git a/packages/app/src/file-pane/editor/view.web.tsx b/packages/app/src/file-pane/editor/view.web.tsx index 8b04590d28..c2749b9c05 100644 --- a/packages/app/src/file-pane/editor/view.web.tsx +++ b/packages/app/src/file-pane/editor/view.web.tsx @@ -4,7 +4,7 @@ import { Annotation, Compartment, EditorState, Transaction } from "@codemirror/s import { EditorView } from "@codemirror/view"; import { getLanguageForFile } from "@getpaseo/highlight"; import { getCM, vim } from "@replit/codemirror-vim"; -import { isRenderedMarkdownFile } from "@/components/file-pane-render-mode"; +import { isRenderedMarkdownFile } from "@/file-panels"; import type { WorkspaceFileLocation } from "@/workspace/file-open"; import type { FileEditorModel } from "./model"; import { editorBaseExtensions, editorTheme, type EditorVisualTheme } from "./extensions.web"; diff --git a/packages/app/src/file-pane/pane.tsx b/packages/app/src/file-pane/pane.tsx index ea3c5b1edb..8e43931677 100644 --- a/packages/app/src/file-pane/pane.tsx +++ b/packages/app/src/file-pane/pane.tsx @@ -1,20 +1,13 @@ import { Button } from "@/components/ui/button"; import { LoadingSpinner } from "@/components/ui/loading-spinner"; -import React, { - useCallback, - useEffect, - useMemo, - useRef, - useState, - useSyncExternalStore, -} from "react"; +import React, { useCallback, useEffect, useMemo, useState, useSyncExternalStore } from "react"; import type { DaemonClient } from "@getpaseo/client/internal/daemon-client"; -import { ScrollView as RNScrollView, Text, View } from "react-native"; +import { Text, View } from "react-native"; import { StyleSheet, UnistylesRuntime, withUnistyles } from "react-native-unistyles"; import { useTranslation } from "react-i18next"; import { useIsCompactFormFactor } from "@/constants/layout"; import { useSessionStore, type ExplorerFile } from "@/stores/session-store"; -import { filePreviewRenderKind } from "@/components/file-pane-render-mode"; +import { FilePanelPreview, resolveFilePreviewPanel, type FilePanel } from "@/file-panels"; import { useAttachmentPreviewUrl } from "@/attachments/use-attachment-preview-url"; import { getFileNameFromPath } from "@/attachments/utils"; import { resolveFilePreviewReadTarget } from "@/file-explorer/preview-target"; @@ -28,8 +21,6 @@ import { useLiveFile } from "./live-file/hook"; import { useFilePreview } from "./preview-lifecycle/hook"; import { resolveFilePreviewLifecycle } from "./preview-lifecycle/model"; import { FilePanelBar } from "./bar"; -import { FileHtmlPreview } from "./html-preview"; -import { FileMarkdownPreview } from "./markdown-preview"; import { FileEditorModel, getFileConflictCallout, type FileConflictCallout } from "./editor/model"; import { createFileObservationSource } from "./editor/observation-source"; import { FileEditorView } from "./editor/view"; @@ -39,7 +30,6 @@ import type { LiveFileModel } from "./live-file/model"; import { confirmDialog } from "@/utils/confirm-dialog"; import { usePublishPanelInstanceAttributes } from "@/panels/panel-instance-attributes"; import type { Theme } from "@/styles/theme"; -import { ZoomableImage } from "@/components/zoomable-viewport/image"; const ThemedLoadingSpinner = withUnistyles(LoadingSpinner); const foregroundMutedColorMapping = (theme: Theme) => ({ @@ -47,6 +37,7 @@ const foregroundMutedColorMapping = (theme: Theme) => ({ }); interface FilePreviewBodyProps { + panel: FilePanel | null; preview: ExplorerFile | null; mode?: "preview" | "source"; isLoading: boolean; @@ -131,6 +122,7 @@ function TooLargeSource({ size }: { size?: number }) { } function FilePreviewBody({ + panel, preview, mode, isLoading, @@ -144,14 +136,6 @@ function FilePreviewBody({ }: FilePreviewBodyProps) { const { t } = useTranslation(); const filePath = location.path; - // A line target means the caller wants to land on that line, so fall back to - // the highlighted source view even for renderable files. - const renderKind = - preview?.kind === "text" && !location.lineStart && mode !== "source" - ? filePreviewRenderKind(filePath) - : null; - - const previewScrollRef = useRef(null); if (isLoading && !preview) { return ( @@ -170,36 +154,21 @@ function FilePreviewBody({ ); } + const showSource = preview.kind === "text" && (Boolean(location.lineStart) || mode === "source"); + if (panel && !showSource) { + return ( + + ); + } if (preview.kind === "text") { - if (renderKind === "html") { - // The HTML document owns its own scrolling, so no ScrollView wrapper here. - return ( - - - - ); - } - - if (renderKind === "markdown") { - return ( - - - - - - ); - } - return ( - - {t("panels.file.loading")} - - ); - } - - return ; - } - return ( {t("panels.file.binaryPreviewUnavailable")} @@ -243,6 +199,7 @@ export function FilePane({ navigationRevision: number; }) { const { t } = useTranslation(); + const { settings } = useAppSettings(); const isMobile = useIsCompactFormFactor(); const [previewMode, setPreviewMode] = useState<"preview" | "source">("preview"); @@ -292,7 +249,12 @@ export function FilePane({ const { file: preview, imageAttachment } = resolveFilePreviewLifecycle(previewLifecycle); const imagePreviewUri = useAttachmentPreviewUrl(imageAttachment); - const isRenderable = isRenderablePreview(preview, location.path); + const panel = resolveFilePreviewPanel({ + preview, + path: location.path, + associations: settings.filePanelAssociations, + }); + const isRenderable = preview?.kind === "text" && panel !== null; const editable = isEditableTextFile({ preview, supportsEditing, @@ -308,6 +270,7 @@ export function FilePane({ return ( ) : null} ) : ( ({ color: theme.colors.foregroundMuted, fontSize: theme.fontSize.base, }, - previewScrollContainer: { - flex: 1, - minHeight: 0, - }, - previewContent: { - flex: 1, - minHeight: 0, - }, - previewCodeScrollContent: { - padding: theme.spacing[4], - }, })); diff --git a/packages/app/src/file-panels/builtin.tsx b/packages/app/src/file-panels/builtin.tsx new file mode 100644 index 0000000000..ba1c4e2cd3 --- /dev/null +++ b/packages/app/src/file-panels/builtin.tsx @@ -0,0 +1,92 @@ +import type { DaemonClient } from "@getpaseo/client/internal/daemon-client"; +import { ScrollView, Text, View } from "react-native"; +import { StyleSheet, withUnistyles } from "react-native-unistyles"; +import { useTranslation } from "react-i18next"; +import { LoadingSpinner } from "@/components/ui/loading-spinner"; +import { ZoomableImage } from "@/components/zoomable-viewport/image"; +import type { Theme } from "@/styles/theme"; +import { FileHtmlPreview } from "./html-preview"; +import { FileMarkdownPreview } from "./markdown-preview"; +import type { builtinFilePanels } from "./catalog"; + +interface FilePanelPreviewProps { + content: string; + filePath: string; + workspaceRoot: string; + client: DaemonClient | null; + serverId: string; + imagePreviewUri: string | null; +} + +function MarkdownPanel(props: FilePanelPreviewProps) { + return ( + + + + + + ); +} + +function HtmlPanel({ content }: FilePanelPreviewProps) { + return ( + + + + ); +} + +const ThemedLoadingSpinner = withUnistyles(LoadingSpinner); +const foregroundMutedColorMapping = (theme: Theme) => ({ color: theme.colors.foregroundMuted }); + +function ImagePanel({ imagePreviewUri }: FilePanelPreviewProps) { + const { t } = useTranslation(); + if (!imagePreviewUri) { + return ( + + + {t("panels.file.loading")} + + ); + } + return ; +} + +const components = { + "builtin:markdown": MarkdownPanel, + "builtin:html": HtmlPanel, + "builtin:image": ImagePanel, +}; + +export function FilePanelPreview({ + panel, + ...props +}: FilePanelPreviewProps & { + panel: (typeof builtinFilePanels)[number]; +}) { + const Component = components[panel.id]; + return ; +} + +const styles = StyleSheet.create((theme) => ({ + previewScrollContainer: { flex: 1, minHeight: 0 }, + previewContent: { flex: 1, minHeight: 0 }, + centerState: { + flex: 1, + alignItems: "center", + justifyContent: "center", + gap: theme.spacing[3], + padding: theme.spacing[4], + }, + loadingText: { + marginTop: theme.spacing[2], + color: theme.colors.foregroundMuted, + fontSize: theme.fontSize.base, + }, +})); diff --git a/packages/app/src/components/file-pane-render-mode.test.ts b/packages/app/src/file-panels/catalog.test.ts similarity index 50% rename from packages/app/src/components/file-pane-render-mode.test.ts rename to packages/app/src/file-panels/catalog.test.ts index 7a0bcf21ec..2052224db2 100644 --- a/packages/app/src/components/file-pane-render-mode.test.ts +++ b/packages/app/src/file-panels/catalog.test.ts @@ -1,5 +1,15 @@ import { describe, expect, it } from "vitest"; -import { filePreviewRenderKind, isRenderedMarkdownFile } from "@/components/file-pane-render-mode"; +import { builtinFilePanels, isRenderedMarkdownFile } from "./catalog"; +import { resolveFilePanel } from "./resolve"; + +function filePreviewRenderKind(path: string) { + const { panel } = resolveFilePanel({ + file: { path, kind: "text", size: 100, hasBytes: false }, + candidates: builtinFilePanels, + associations: {}, + }); + return panel ? panel.id.slice("builtin:".length) : null; +} describe("isRenderedMarkdownFile", () => { it("detects .md files", () => { @@ -38,3 +48,39 @@ describe("filePreviewRenderKind", () => { expect(filePreviewRenderKind("index.html.erb")).toBe(null); }); }); + +describe("built-in file panels", () => { + it.each(["png", "jpg", "jpeg", "gif", "webp", "svg"])( + "registers the image extension %s", + (extension) => { + const resolution = resolveFilePanel({ + file: { + path: `/capture.${extension.toUpperCase()}`, + kind: "image", + size: 512, + hasBytes: true, + }, + candidates: builtinFilePanels, + associations: { [`ext:${extension}`]: "builtin:markdown" }, + }); + expect(resolution.panel?.id).toBe("builtin:image"); + expect( + resolveFilePanel({ + file: { path: "capture.png", kind: "binary", size: 512, hasBytes: false }, + candidates: builtinFilePanels, + associations: {}, + }).panel, + ).toBeNull(); + }, + ); + + it("does not impose a new preview size limit on built-in text panels", () => { + expect( + resolveFilePanel({ + file: { path: "notes.md", kind: "text", size: 11 * 1024 * 1024, hasBytes: false }, + candidates: builtinFilePanels, + associations: {}, + }).panel?.id, + ).toBe("builtin:markdown"); + }); +}); diff --git a/packages/app/src/file-panels/catalog.ts b/packages/app/src/file-panels/catalog.ts new file mode 100644 index 0000000000..fd350ec1ff --- /dev/null +++ b/packages/app/src/file-panels/catalog.ts @@ -0,0 +1,28 @@ +import { filePanelExtension, type FilePanelCandidate } from "./resolve"; + +const markdownPanel = { + id: "builtin:markdown", + files: { extensions: ["md", "markdown"] }, + document: "text", + maxBytes: Infinity, +} as const satisfies FilePanelCandidate; + +export const builtinFilePanels = [ + markdownPanel, + { + id: "builtin:html", + files: { extensions: ["html", "htm"] }, + document: "text", + maxBytes: Infinity, + }, + { + id: "builtin:image", + files: { extensions: ["png", "jpg", "jpeg", "gif", "webp", "svg"] }, + document: "bytes", + maxBytes: Infinity, + }, +] as const satisfies readonly FilePanelCandidate[]; + +export function isRenderedMarkdownFile(path: string): boolean { + return markdownPanel.files.extensions.some((extension) => extension === filePanelExtension(path)); +} diff --git a/packages/app/src/file-pane/html-preview-csp.test.ts b/packages/app/src/file-panels/html-preview-csp.test.ts similarity index 96% rename from packages/app/src/file-pane/html-preview-csp.test.ts rename to packages/app/src/file-panels/html-preview-csp.test.ts index bbf3bbb745..ad713f5910 100644 --- a/packages/app/src/file-pane/html-preview-csp.test.ts +++ b/packages/app/src/file-panels/html-preview-csp.test.ts @@ -1,5 +1,5 @@ import { describe, expect, it } from "vitest"; -import { withPreviewCsp } from "@/file-pane/html-preview-csp"; +import { withPreviewCsp } from "./html-preview-csp"; describe("withPreviewCsp", () => { it("places the policy before the complete source document", () => { diff --git a/packages/app/src/file-pane/html-preview-csp.ts b/packages/app/src/file-panels/html-preview-csp.ts similarity index 100% rename from packages/app/src/file-pane/html-preview-csp.ts rename to packages/app/src/file-panels/html-preview-csp.ts diff --git a/packages/app/src/file-pane/html-preview-navigation.test.ts b/packages/app/src/file-panels/html-preview-navigation.test.ts similarity index 92% rename from packages/app/src/file-pane/html-preview-navigation.test.ts rename to packages/app/src/file-panels/html-preview-navigation.test.ts index e2029085af..3aa3c14d6a 100644 --- a/packages/app/src/file-pane/html-preview-navigation.test.ts +++ b/packages/app/src/file-panels/html-preview-navigation.test.ts @@ -1,5 +1,5 @@ import { describe, expect, it } from "vitest"; -import { htmlPreviewNavigationKind } from "@/file-pane/html-preview-navigation"; +import { htmlPreviewNavigationKind } from "./html-preview-navigation"; describe("htmlPreviewNavigationKind", () => { it("allows the WebView's initial document URLs", () => { diff --git a/packages/app/src/file-pane/html-preview-navigation.ts b/packages/app/src/file-panels/html-preview-navigation.ts similarity index 100% rename from packages/app/src/file-pane/html-preview-navigation.ts rename to packages/app/src/file-panels/html-preview-navigation.ts diff --git a/packages/app/src/file-pane/html-preview.tsx b/packages/app/src/file-panels/html-preview.tsx similarity index 100% rename from packages/app/src/file-pane/html-preview.tsx rename to packages/app/src/file-panels/html-preview.tsx diff --git a/packages/app/src/file-pane/html-preview.web.tsx b/packages/app/src/file-panels/html-preview.web.tsx similarity index 100% rename from packages/app/src/file-pane/html-preview.web.tsx rename to packages/app/src/file-panels/html-preview.web.tsx diff --git a/packages/app/src/file-panels/index.ts b/packages/app/src/file-panels/index.ts new file mode 100644 index 0000000000..497e3aba2e --- /dev/null +++ b/packages/app/src/file-panels/index.ts @@ -0,0 +1,23 @@ +import type { ExplorerFile } from "@/stores/session-store"; +import { builtinFilePanels } from "./catalog"; +import { resolveFilePanel } from "./resolve"; + +export { resolveFilePanel, type FilePanelCandidate, type FilePanelFile } from "./resolve"; +export { builtinFilePanels, isRenderedMarkdownFile } from "./catalog"; +export { FilePanelPreview } from "./builtin"; + +export type FilePanel = (typeof builtinFilePanels)[number]; + +export function resolveFilePreviewPanel(input: { + preview: ExplorerFile | null; + path: string; + associations: Readonly>; +}) { + const { preview, path, associations } = input; + if (!preview) return null; + return resolveFilePanel({ + file: { path, kind: preview.kind, size: preview.size, hasBytes: preview.kind === "image" }, + candidates: builtinFilePanels, + associations, + }).panel; +} diff --git a/packages/app/src/file-pane/markdown-preview/document.test.ts b/packages/app/src/file-panels/markdown-preview/document.test.ts similarity index 100% rename from packages/app/src/file-pane/markdown-preview/document.test.ts rename to packages/app/src/file-panels/markdown-preview/document.test.ts diff --git a/packages/app/src/file-pane/markdown-preview/document.ts b/packages/app/src/file-panels/markdown-preview/document.ts similarity index 100% rename from packages/app/src/file-pane/markdown-preview/document.ts rename to packages/app/src/file-panels/markdown-preview/document.ts diff --git a/packages/app/src/file-pane/markdown-preview/index.tsx b/packages/app/src/file-panels/markdown-preview/index.tsx similarity index 100% rename from packages/app/src/file-pane/markdown-preview/index.tsx rename to packages/app/src/file-panels/markdown-preview/index.tsx diff --git a/packages/app/src/file-panels/resolve.test.ts b/packages/app/src/file-panels/resolve.test.ts new file mode 100644 index 0000000000..4bac78b4da --- /dev/null +++ b/packages/app/src/file-panels/resolve.test.ts @@ -0,0 +1,105 @@ +import { describe, expect, it } from "vitest"; +import { resolveFilePanel, type FilePanelCandidate, type FilePanelFile } from "./resolve"; + +const markdown: FilePanelCandidate = { + id: "builtin:markdown", + files: { extensions: ["md", "markdown"] }, + document: "text", + maxBytes: Infinity, +}; +const alternative: FilePanelCandidate = { ...markdown, id: "plugin:notes/markdown" }; +const file: FilePanelFile = { path: "/docs/README.MD", kind: "text", size: 100, hasBytes: true }; + +function resolve( + overrides: Partial>[0]> = {}, +) { + return resolveFilePanel({ + file, + candidates: [markdown, alternative], + associations: {}, + ...overrides, + }); +} + +describe("resolveFilePanel", () => { + it("uses the associated candidate before catalog order", () => { + expect(resolve({ associations: { "ext:md": alternative.id } })).toEqual({ + panel: alternative, + candidates: [markdown, alternative], + selectorKey: "ext:md", + }); + }); + it("ignores an absent association without deleting it", () => { + const associations = { "ext:md": "plugin:absent/markdown" }; + expect(resolve({ associations }).panel).toBe(markdown); + expect(associations).toEqual({ "ext:md": "plugin:absent/markdown" }); + }); + it("uses a single candidate and preserves catalog order for multiple candidates", () => { + expect(resolve({ candidates: [alternative] }).panel).toBe(alternative); + expect(resolve().panel).toBe(markdown); + expect(resolve({ candidates: [alternative, markdown] }).panel).toBe(alternative); + }); + it("returns the floor when no selector matches", () => { + expect(resolve({ file: { ...file, path: "index.ts" } })).toEqual({ + panel: null, + candidates: [], + selectorKey: "ext:ts", + }); + }); + it("filters text panels for binary files even with an association", () => { + expect( + resolve({ file: { ...file, kind: "binary" }, associations: { "ext:md": markdown.id } }).panel, + ).toBeNull(); + }); + it("requires bytes for bytes panels and accepts binary files with bytes", () => { + const bytes: FilePanelCandidate = { ...alternative, document: "bytes" }; + expect(resolve({ file: { ...file, hasBytes: false }, candidates: [bytes] }).panel).toBeNull(); + expect(resolve({ file: { ...file, kind: "binary" }, candidates: [bytes] }).panel).toBe(bytes); + }); + it("includes the maxBytes boundary and skips oversized associated panels", () => { + const limited = { ...alternative, maxBytes: 100 }; + expect(resolve({ candidates: [limited] }).panel).toBe(limited); + expect( + resolve({ + file: { ...file, size: 101 }, + candidates: [limited, markdown], + associations: { "ext:md": limited.id }, + }).panel, + ).toBe(markdown); + }); + it("uses exact basename keys when an eligible candidate matches by filename", () => { + const named = { ...alternative, files: { extensions: [], filenames: ["README.MD"] } }; + expect( + resolve({ candidates: [markdown, named], associations: { "name:README.MD": named.id } }), + ).toEqual({ + panel: named, + candidates: [markdown, named], + selectorKey: "name:README.MD", + }); + expect(resolve({ file: { ...file, path: "README.md" }, candidates: [named] }).panel).toBeNull(); + }); + it("uses extension keys when filename candidates were filtered out", () => { + const named = { + ...alternative, + maxBytes: 1, + files: { extensions: [], filenames: ["README.MD"] }, + }; + expect(resolve({ candidates: [named, markdown] }).selectorKey).toBe("ext:md"); + }); + it.each(["/src/Dockerfile", "C:\\src\\Dockerfile"])( + "matches an extensionless exact filename: %s", + (path) => { + const named = { ...alternative, files: { extensions: [], filenames: ["Dockerfile"] } }; + expect(resolve({ file: { ...file, path }, candidates: [named] })).toEqual({ + panel: named, + candidates: [named], + selectorKey: "name:Dockerfile", + }); + }, + ); + it("normalizes extension selectors and keeps extensionless files distinct", () => { + const upper = { ...alternative, files: { extensions: ["MD"] } }; + expect(resolve({ candidates: [upper] }).panel).toBe(upper); + expect(resolve({ file: { ...file, path: "README" } }).selectorKey).toBe("ext:"); + }); +}); diff --git a/packages/app/src/file-panels/resolve.ts b/packages/app/src/file-panels/resolve.ts new file mode 100644 index 0000000000..3ede7993de --- /dev/null +++ b/packages/app/src/file-panels/resolve.ts @@ -0,0 +1,63 @@ +export interface FilePanelFile { + path: string; + kind: "text" | "image" | "binary"; + size: number; + hasBytes: boolean; +} + +export interface FilePanelSelector { + extensions: readonly string[]; + filenames?: readonly string[]; +} + +export interface FilePanelCandidate { + id: string; + files: FilePanelSelector; + document: "text" | "bytes"; + maxBytes: number; +} + +export interface FilePanelResolution { + panel: Candidate | null; + candidates: readonly Candidate[]; + selectorKey: string; +} + +export function filePanelExtension(path: string): string { + const name = filePanelBasename(path); + const dot = name.lastIndexOf("."); + return dot < 0 ? "" : name.slice(dot + 1).toLowerCase(); +} + +function filePanelBasename(path: string): string { + return path.trim().split(/[\\/]/).pop() ?? ""; +} + +function matchesSelector(file: FilePanelFile, selector: FilePanelSelector): boolean { + if (selector.filenames?.includes(filePanelBasename(file.path))) return true; + const extension = filePanelExtension(file.path); + return selector.extensions.some((entry) => entry.toLowerCase() === extension); +} + +export function resolveFilePanel(input: { + file: FilePanelFile; + candidates: readonly Candidate[]; + associations: Readonly>; +}): FilePanelResolution { + const { file, associations } = input; + const candidates = input.candidates.filter((candidate) => { + const documentAvailable = candidate.document === "text" ? file.kind === "text" : file.hasBytes; + return ( + documentAvailable && file.size <= candidate.maxBytes && matchesSelector(file, candidate.files) + ); + }); + const filename = filePanelBasename(file.path); + const matchedFilename = candidates.some((candidate) => + candidate.files.filenames?.includes(filename), + ); + const selectorKey = matchedFilename ? `name:${filename}` : `ext:${filePanelExtension(file.path)}`; + const association = associations[selectorKey]; + const panel = + candidates.find((candidate) => candidate.id === association) ?? candidates[0] ?? null; + return { panel, candidates, selectorKey }; +} diff --git a/packages/app/src/git/actions-split-button.tsx b/packages/app/src/git/actions-split-button.tsx index 193154b377..64a550f144 100644 --- a/packages/app/src/git/actions-split-button.tsx +++ b/packages/app/src/git/actions-split-button.tsx @@ -15,7 +15,7 @@ import { Shortcut } from "@/components/ui/shortcut"; import { useShortcutKeys } from "@/hooks/use-shortcut-keys"; import { inlineUnistylesStyle } from "@/styles/unistyles-inline-style"; import type { ShortcutKey } from "@/utils/format-shortcut"; -import type { GitAction, GitActions } from "@/git/policy"; +import { actionsWithoutPrimary, type GitAction, type GitActions } from "@/git/policy"; import { useGitActionRunner } from "@/git/use-actions"; import { buttonControlHeight, HEADER_CONTROL_HEIGHT } from "@/components/ui/control-geometry"; @@ -129,14 +129,10 @@ export function GitActionsSplitButton({ [theme.colors.surface2], ); - const menuOnlyActions = useMemo( - () => [ - ...(gitActions.primary ? [gitActions.primary] : []), - ...gitActions.secondary, - ...gitActions.menu, - ], - [gitActions.menu, gitActions.primary, gitActions.secondary], - ); + const menuOnlyActions = [ + ...(gitActions.primary ? [gitActions.primary] : []), + ...actionsWithoutPrimary(gitActions), + ]; if (menuOnly) { if (menuOnlyActions.length === 0) { diff --git a/packages/app/src/git/policy.test.ts b/packages/app/src/git/policy.test.ts index 561bbc75e6..efbd61efa6 100644 --- a/packages/app/src/git/policy.test.ts +++ b/packages/app/src/git/policy.test.ts @@ -2,7 +2,7 @@ import { afterEach, describe, expect, it } from "vitest"; import { CheckoutPrStatusSchema } from "@getpaseo/protocol/messages"; import { i18n } from "@/i18n/i18next"; -import { buildGitActions, type BuildGitActionsInput } from "./policy"; +import { actionsWithoutPrimary, buildGitActions, type BuildGitActionsInput } from "./policy"; import { deriveMergeCapability, type ForgeSpecificStatusFacts } from "./merge-capability"; type GithubMergeFactsFixture = ForgeSpecificStatusFacts & { @@ -190,6 +190,59 @@ describe("git-actions-policy", () => { expect(actions.primary).toMatchObject({ id: "pull", label: "Pull" }); }); + it("drops a promoted remote action from the remaining menu actions", () => { + const pull = buildGitActions(createInput({ hasRemote: true, behindOfOrigin: 2 })); + expect(pull.primary?.id).toBe("pull"); + expect(actionsWithoutPrimary(pull).map((action) => action.id)).toEqual([ + "push", + "pull-and-push", + "archive-workspace", + ]); + + const push = buildGitActions(createInput({ hasRemote: true, aheadOfOrigin: 1 })); + expect(push.primary?.id).toBe("push"); + expect(actionsWithoutPrimary(push).map((action) => action.id)).toEqual([ + "pull", + "pull-and-push", + "archive-workspace", + ]); + }); + + it("drops a promoted merge action from the remaining menu actions", () => { + const actions = buildGitActions( + createInput({ + hasRemote: true, + isOnBaseBranch: false, + aheadCount: 2, + hasPullRequest: true, + pullRequestUrl: "https://example.com/pr/456", + pullRequestState: "open", + pullRequestMergeable: "MERGEABLE", + pullRequestGithub: githubStatus({ + repository: { + autoMergeAllowed: true, + mergeCommitAllowed: true, + squashMergeAllowed: false, + rebaseMergeAllowed: false, + viewerDefaultMergeMethod: "SQUASH", + }, + }), + shipDefault: "pr", + }), + ); + + expect(actions.primary).toMatchObject({ id: "merge-pr-merge", label: "Merge PR (merge)" }); + expect(actionsWithoutPrimary(actions).map((action) => action.id)).toEqual([ + "pull", + "push", + "pull-and-push", + "merge-from-base", + "merge-branch", + "pr", + "archive-workspace", + ]); + }); + it("keeps push clickable with a clearer message when the branch diverged", () => { const actions = buildGitActions( createInput({ diff --git a/packages/app/src/git/policy.ts b/packages/app/src/git/policy.ts index eb6e28399b..71d63eae37 100644 --- a/packages/app/src/git/policy.ts +++ b/packages/app/src/git/policy.ts @@ -312,6 +312,18 @@ export function buildGitActions(input: BuildGitActionsInput): GitActions { }; } +/** + * The actions a flattened list shows after the primary. `secondary` keeps the actions the policy + * can promote to `primary`, and the translator rebuilds those objects, so a flattening consumer + * has to drop the promoted one by id or it renders it twice. + */ +export function actionsWithoutPrimary(gitActions: GitActions): GitAction[] { + const primaryActionId = gitActions.primary?.id; + return [...gitActions.secondary, ...gitActions.menu].filter( + (action) => action.id !== primaryActionId, + ); +} + function getPrimaryActionId(input: BuildGitActionsInput): GitActionId | null { if (input.shouldPromoteArchive) { return "archive-workspace"; diff --git a/packages/app/src/hooks/use-acp-provider-catalog.test.ts b/packages/app/src/hooks/use-acp-provider-catalog.test.ts index 201c17c022..c5fd59d53e 100644 --- a/packages/app/src/hooks/use-acp-provider-catalog.test.ts +++ b/packages/app/src/hooks/use-acp-provider-catalog.test.ts @@ -11,6 +11,13 @@ function findProvider(id: string) { } describe("ACP provider catalog", () => { + it.each(["devin", "hermes", "kiro"])( + "#7087: %s supplies its provider mark to the catalog picker", + (provider) => { + expect(findProvider(provider).iconSvg).toContain(" { const ids = new Set(); diff --git a/packages/app/src/hooks/use-agent-form-state.ts b/packages/app/src/hooks/use-agent-form-state.ts index 26908bd6a0..1522ce082e 100644 --- a/packages/app/src/hooks/use-agent-form-state.ts +++ b/packages/app/src/hooks/use-agent-form-state.ts @@ -36,6 +36,7 @@ import { type FormState, type ProviderModelsByProvider, } from "@/provider-selection/resolve-agent-form"; +import { useHostRuntimeIsConnected } from "@/runtime/host-runtime"; import type { MaterializedAgentProfile } from "@/agent-profiles"; export type { FormInitialValues } from "@/provider-selection/resolve-agent-form"; @@ -186,6 +187,8 @@ export function useAgentFormState(options: UseAgentFormStateOptions): UseAgentFo refetchIfStale: refetchSnapshotIfStale, } = useProvidersSnapshot(serverId, { cwd: workingDir }); + const isConnected = useHostRuntimeIsConnected(serverId ?? ""); + const allProviderEntries = useMemo(() => snapshotEntries ?? [], [snapshotEntries]); const snapshotProviderDefinitions = useMemo( () => buildProviderDefinitions(snapshotEntries), @@ -220,8 +223,8 @@ export function useAgentFormState(options: UseAgentFormStateOptions): UseAgentFo [snapshotEntries], ); const snapshotModelSelectorProviders = useMemo( - () => buildSelectableProviderSelectorProviders(snapshotEntries), - [snapshotEntries], + () => buildSelectableProviderSelectorProviders(snapshotEntries, isConnected), + [snapshotEntries, isConnected], ); const snapshotSelectedEntry = useMemo( () => @@ -247,7 +250,8 @@ export function useAgentFormState(options: UseAgentFormStateOptions): UseAgentFo const availableModels = snapshotSelectedProviderModels; const modeOptions = snapshotSelectedProviderModes; const isModelSelectionLoading = - resolution.status === "pending" || snapshotIsLoading || selectedProviderIsLoading; + isConnected && + (resolution.status === "pending" || snapshotIsLoading || selectedProviderIsLoading); const isAllModelsLoading = isModelSelectionLoading; useEffect(() => { diff --git a/packages/app/src/hooks/use-settings/storage.test.ts b/packages/app/src/hooks/use-settings/storage.test.ts index 6d9c8d4c7c..323868280f 100644 --- a/packages/app/src/hooks/use-settings/storage.test.ts +++ b/packages/app/src/hooks/use-settings/storage.test.ts @@ -44,6 +44,33 @@ function makeDeps( } describe("loadAppSettingsFromStorage", () => { + it("persists file panel associations, including panels absent from this host", async () => { + const deps = makeDeps(); + const queryClient = new QueryClient(); + const filePanelAssociations = { + "ext:md": "builtin:markdown", + "name:Dockerfile": "plugin:absent/container", + }; + await saveAppSettings({ queryClient, deps, updates: { filePanelAssociations } }); + expect((await loadAppSettingsFromStorage(deps)).filePanelAssociations).toEqual( + filePanelAssociations, + ); + }); + + it.each([undefined, null, [], "invalid", { "ext:md": 42 }])( + "defaults malformed file panel associations without discarding other settings: %j", + async (filePanelAssociations) => { + const deps = makeDeps({ + storage: createInMemoryKeyValueStorage({ + [APP_SETTINGS_KEY]: JSON.stringify({ filePanelAssociations, vimKeybindings: true }), + }), + }); + const settings = await loadAppSettingsFromStorage(deps); + expect(settings.filePanelAssociations).toEqual({}); + expect(settings.vimKeybindings).toBe(true); + }, + ); + it("preserves a persisted steer send behavior", async () => { const deps = makeDeps({ storage: createInMemoryKeyValueStorage({ diff --git a/packages/app/src/hooks/use-settings/storage.ts b/packages/app/src/hooks/use-settings/storage.ts index 54ee6b10bc..d3b918755f 100644 --- a/packages/app/src/hooks/use-settings/storage.ts +++ b/packages/app/src/hooks/use-settings/storage.ts @@ -104,6 +104,7 @@ export interface AppSettings { toolCallDetailLevel: ToolCallDetailLevel; chatOutlineEnabled: boolean; vimKeybindings: boolean; + filePanelAssociations: Record; /** Desktop-only preferences for implicit opens into the ordinary side pane. */ openInSidePane: OpenInSidePanePreferences; pullRequestOpenLocation: PullRequestOpenLocation; @@ -160,6 +161,7 @@ export const DEFAULT_CLIENT_SETTINGS: AppSettings = { toolCallDetailLevel: "detailed", chatOutlineEnabled: true, vimKeybindings: false, + filePanelAssociations: {}, openInSidePane: DEFAULT_OPEN_IN_SIDE_PANE_PREFERENCES, pullRequestOpenLocation: "explorer", }; @@ -261,6 +263,7 @@ const StoredAppSettingsSchema = z compactToolCalls: z.boolean().optional().catch(undefined), chatOutlineEnabled: z.boolean().catch(true), vimKeybindings: z.boolean().catch(false), + filePanelAssociations: z.record(z.string(), z.string()).catch({}), openInSidePane: z .object({ explorerFiles: z.boolean().catch(false), diff --git a/packages/app/src/i18n/resources/ar.ts b/packages/app/src/i18n/resources/ar.ts index 4adf945b61..b7b81c66ee 100644 --- a/packages/app/src/i18n/resources/ar.ts +++ b/packages/app/src/i18n/resources/ar.ts @@ -538,6 +538,7 @@ export const ar: TranslationResources = { }, }, setup: { + updateHost: "حدّث المضيف لعرض تفاصيل إعداد مساحة العمل", descriptor: { label: "يثبت", completed: "اكتمل الإعداد", @@ -2333,6 +2334,7 @@ export const ar: TranslationResources = { searchPlaceholder: "البحث في الاختصارات", unavailableOnMobile: "اختصارات لوحة المفاتيح متاحة فقط على سطح المكتب", capturePrompt: "اضغط على الاختصار...", + captureIndexPrompt: "اختم برقم من 1 إلى 9.", unassigned: "غير معين", actions: { menu: "إجراءات {{name}}", diff --git a/packages/app/src/i18n/resources/en.ts b/packages/app/src/i18n/resources/en.ts index 9bb0460036..d8a4081dda 100644 --- a/packages/app/src/i18n/resources/en.ts +++ b/packages/app/src/i18n/resources/en.ts @@ -535,6 +535,7 @@ export const en = { }, }, setup: { + updateHost: "Update the host to view workspace setup details", descriptor: { label: "Setup", completed: "Setup completed", @@ -2456,6 +2457,7 @@ export const en = { searchPlaceholder: "Search shortcuts", unavailableOnMobile: "Keyboard shortcuts are only available on desktop", capturePrompt: "Press shortcut...", + captureIndexPrompt: "End with a number from 1 to 9.", unassigned: "Not set", actions: { menu: "Actions for {{name}}", diff --git a/packages/app/src/i18n/resources/es.ts b/packages/app/src/i18n/resources/es.ts index 9ed1e85572..7fba1c22b9 100644 --- a/packages/app/src/i18n/resources/es.ts +++ b/packages/app/src/i18n/resources/es.ts @@ -544,6 +544,7 @@ export const es: TranslationResources = { }, }, setup: { + updateHost: "Actualiza el host para ver los detalles de configuración del espacio de trabajo", descriptor: { label: "Configuración", completed: "Configuración completada", @@ -2387,6 +2388,7 @@ export const es: TranslationResources = { searchPlaceholder: "Buscar atajos", unavailableOnMobile: "Los atajos de teclado solo están disponibles en el escritorio", capturePrompt: "Presione el acceso directo...", + captureIndexPrompt: "Termina con un número del 1 al 9.", unassigned: "Sin asignar", actions: { menu: "Acciones para {{name}}", diff --git a/packages/app/src/i18n/resources/fr.ts b/packages/app/src/i18n/resources/fr.ts index 6563b1100e..54b6de6098 100644 --- a/packages/app/src/i18n/resources/fr.ts +++ b/packages/app/src/i18n/resources/fr.ts @@ -543,6 +543,8 @@ export const fr: TranslationResources = { }, }, setup: { + updateHost: + "Mettez à jour l’hôte pour afficher les détails de configuration de l’espace de travail", descriptor: { label: "Configuration", completed: "Configuration terminée", @@ -2387,6 +2389,7 @@ export const fr: TranslationResources = { searchPlaceholder: "Rechercher des raccourcis", unavailableOnMobile: "Les raccourcis clavier ne sont disponibles que sur l’app de bureau", capturePrompt: "Appuyez sur le raccourci…", + captureIndexPrompt: "Terminez par un chiffre de 1 à 9.", unassigned: "Non attribué", actions: { menu: "Actions pour {{name}}", diff --git a/packages/app/src/i18n/resources/ja.ts b/packages/app/src/i18n/resources/ja.ts index eb22dd663a..31f1d4241f 100644 --- a/packages/app/src/i18n/resources/ja.ts +++ b/packages/app/src/i18n/resources/ja.ts @@ -544,6 +544,7 @@ export const ja: TranslationResources = { }, }, setup: { + updateHost: "ワークスペースのセットアップ詳細を表示するにはホストを更新してください", descriptor: { label: "セットアップ", completed: "セットアップ完了", @@ -2354,6 +2355,7 @@ export const ja: TranslationResources = { searchPlaceholder: "ショートカットを検索", unavailableOnMobile: "キーボードショートカットはデスクトップでのみ利用できます", capturePrompt: "ショートカットを押してください...", + captureIndexPrompt: "最後に1〜9の数字を入力してください。", unassigned: "未設定", actions: { menu: "{{name}} のアクション", diff --git a/packages/app/src/i18n/resources/ko.ts b/packages/app/src/i18n/resources/ko.ts index afdb8974e9..1214aa2435 100644 --- a/packages/app/src/i18n/resources/ko.ts +++ b/packages/app/src/i18n/resources/ko.ts @@ -539,6 +539,7 @@ export const ko: TranslationResources = { }, }, setup: { + updateHost: "작업 공간 설정 세부 정보를 보려면 호스트를 업데이트하세요", descriptor: { label: "설정", completed: "설정 완료", @@ -2343,6 +2344,7 @@ export const ko: TranslationResources = { searchPlaceholder: "검색 단축키", unavailableOnMobile: "키보드 단축키는 데스크톱에서만 사용할 수 있습니다", capturePrompt: "단축키를 누르세요...", + captureIndexPrompt: "마지막에 1부터 9까지의 숫자를 입력하세요.", unassigned: "설정되지 않음", actions: { menu: "{{name}} 작업", diff --git a/packages/app/src/i18n/resources/pt-BR.ts b/packages/app/src/i18n/resources/pt-BR.ts index f89fb97bf0..1a24fd1f83 100644 --- a/packages/app/src/i18n/resources/pt-BR.ts +++ b/packages/app/src/i18n/resources/pt-BR.ts @@ -543,6 +543,7 @@ export const ptBR: TranslationResources = { }, }, setup: { + updateHost: "Atualize o host para ver os detalhes da configuração do espaço de trabalho", descriptor: { label: "Configuração", completed: "Configuração concluída", @@ -2368,6 +2369,7 @@ export const ptBR: TranslationResources = { searchPlaceholder: "Pesquisar atalhos", unavailableOnMobile: "Atalhos de teclado estão disponíveis apenas no desktop", capturePrompt: "Pressione o atalho...", + captureIndexPrompt: "Termine com um número de 1 a 9.", unassigned: "Não definido", actions: { menu: "Ações para {{name}}", diff --git a/packages/app/src/i18n/resources/ru.ts b/packages/app/src/i18n/resources/ru.ts index a1a70822b4..3b444895e5 100644 --- a/packages/app/src/i18n/resources/ru.ts +++ b/packages/app/src/i18n/resources/ru.ts @@ -543,6 +543,7 @@ export const ru: TranslationResources = { }, }, setup: { + updateHost: "Обновите хост, чтобы просмотреть сведения о настройке рабочего пространства", descriptor: { label: "Настройка", completed: "Настройка завершена", @@ -2373,6 +2374,7 @@ export const ru: TranslationResources = { searchPlaceholder: "Поиск сочетаний клавиш", unavailableOnMobile: "Сочетания клавиш доступны только на рабочем столе.", capturePrompt: "Нажмите сочетание клавиш...", + captureIndexPrompt: "Завершите цифрой от 1 до 9.", unassigned: "Не задано", actions: { menu: "Действия для {{name}}", diff --git a/packages/app/src/i18n/resources/zh-CN.ts b/packages/app/src/i18n/resources/zh-CN.ts index ca221d7d3a..7b517fafb1 100644 --- a/packages/app/src/i18n/resources/zh-CN.ts +++ b/packages/app/src/i18n/resources/zh-CN.ts @@ -538,6 +538,7 @@ export const zhCN: TranslationResources = { }, }, setup: { + updateHost: "更新主机以查看工作区设置详情", descriptor: { label: "Setup", completed: "Setup 已完成", @@ -2305,6 +2306,7 @@ export const zhCN: TranslationResources = { searchPlaceholder: "搜索快捷键", unavailableOnMobile: "键盘快捷键仅在桌面端可用", capturePrompt: "按下快捷键...", + captureIndexPrompt: "请以 1 到 9 的数字结尾。", unassigned: "未设置", actions: { menu: "{{name}} 的操作", diff --git a/packages/app/src/keyboard/keyboard-shortcuts.test.ts b/packages/app/src/keyboard/keyboard-shortcuts.test.ts index 9e56ef66cd..770d7e710c 100644 --- a/packages/app/src/keyboard/keyboard-shortcuts.test.ts +++ b/packages/app/src/keyboard/keyboard-shortcuts.test.ts @@ -4,7 +4,9 @@ import { keyboardEventToComboString } from "./shortcut-string"; import { buildKeyboardShortcutHelpSections, buildEffectiveBindings, + DEFAULT_BINDINGS, normalizeCapturedShortcutCombo, + isShortcutCaptureComplete, getBindingIdForAction, getDefaultKeysForAction, getWorkspaceIndexJumpModifierKey, @@ -1390,3 +1392,22 @@ describe("number-group shortcut capture", () => { expect(normalizeCapturedShortcutCombo(tabBindingId, "Ctrl+9")).toBe("Ctrl+Digit"); }); }); + +describe("shortcut capture completion", () => { + const indexBindings = DEFAULT_BINDINGS.filter((binding) => binding.payload?.type === "index"); + it.each(indexBindings)("requires a final 1–9 number for $id", ({ id }) => { + for (const combos of [[], ["Ctrl+K"], ["Ctrl+0"], ["Ctrl+Digit", "Ctrl+K"]]) { + expect(isShortcutCaptureComplete(id, combos)).toBe(false); + } + for (let index = 1; index <= 9; index++) { + const combo = normalizeCapturedShortcutCombo(id, `Ctrl+${index}`); + expect(isShortcutCaptureComplete(id, [combo])).toBe(true); + expect(isShortcutCaptureComplete(id, ["Ctrl+K", combo])).toBe(true); + } + }); + it("keeps ordinary shortcuts available without a number", () => { + expect(isShortcutCaptureComplete("show-shortcuts", [])).toBe(false); + expect(isShortcutCaptureComplete("show-shortcuts", ["Ctrl+K"])).toBe(true); + expect(isShortcutCaptureComplete("show-shortcuts", ["Ctrl+0"])).toBe(true); + }); +}); diff --git a/packages/app/src/keyboard/keyboard-shortcuts.ts b/packages/app/src/keyboard/keyboard-shortcuts.ts index a009008b85..9f6329c013 100644 --- a/packages/app/src/keyboard/keyboard-shortcuts.ts +++ b/packages/app/src/keyboard/keyboard-shortcuts.ts @@ -1217,6 +1217,14 @@ export function normalizeCapturedShortcutCombo(bindingId: string, combo: string) return combo.replace(/(^|\+)[1-9]$/, "$1Digit"); } +/** Index navigation needs a final number; earlier combos may be any chord prefix. */ +export function isShortcutCaptureComplete(bindingId: string, combos: readonly string[]): boolean { + const lastCombo = combos.at(-1); + if (!lastCombo) return false; + const binding = DEFAULT_BINDINGS.find((candidate) => candidate.id === bindingId); + return binding?.payload?.type !== "index" || /(^|\+)(Digit|[1-9])$/.test(lastCombo); +} + export function buildEffectiveBindings(overrides: ShortcutOverrides): ParsedShortcutBinding[] { return DEFAULT_BINDINGS.map(function (binding) { const override = overrides[binding.id]; diff --git a/packages/app/src/panels/agent-facts-line.ts b/packages/app/src/panels/agent-facts-line.ts index 7d3cd80332..7c01e5ce42 100644 --- a/packages/app/src/panels/agent-facts-line.ts +++ b/packages/app/src/panels/agent-facts-line.ts @@ -1,7 +1,10 @@ import type { AgentMode, AgentModelDefinition } from "@getpaseo/protocol/agent-types"; +import { useShallow } from "zustand/shallow"; import { formatAgentModeLabel } from "@/agent-controls/labels"; import { formatTokenCount } from "@/components/context-window-meter.utils"; import { resolveAgentModelSelection } from "@/composer/agent-controls/utils"; +import { useProvidersSnapshot } from "@/hooks/use-providers-snapshot"; +import { useSessionStore } from "@/stores/session-store"; export interface AgentFactsInput { models: AgentModelDefinition[] | null; @@ -33,6 +36,32 @@ export function buildAgentFactsLine(input: AgentFactsInput): string | null { return parts.join(" · "); } +/** The facts line for a Paseo agent in the session store, kept current as the agent reports. */ +export function useAgentFactsLine(serverId: string, agentId: string): string | null { + const agent = useSessionStore( + useShallow((state) => { + const current = state.sessions[serverId]?.agents.get(agentId); + return current + ? { + provider: current.provider, + cwd: current.cwd, + runtimeModelId: current.runtimeInfo?.model ?? null, + configuredModelId: current.model ?? null, + runtimeThinkingOptionId: current.runtimeInfo?.thinkingOptionId ?? null, + explicitThinkingOptionId: current.thinkingOptionId ?? null, + availableModes: current.availableModes, + currentModeId: current.currentModeId, + contextWindowUsedTokens: current.lastUsage?.contextWindowUsedTokens ?? null, + contextWindowMaxTokens: current.lastUsage?.contextWindowMaxTokens ?? null, + } + : null; + }), + ); + const { entries } = useProvidersSnapshot(serverId, { cwd: agent?.cwd }); + const models = entries?.find((entry) => entry.provider === agent?.provider)?.models ?? null; + return agent ? buildAgentFactsLine({ ...agent, models }) : null; +} + /** The mode control shows the current mode, or the provider's first one until the agent reports. */ function resolveModeLabel(modes: AgentMode[], currentModeId: string | null | undefined) { const mode = modes.find((candidate) => candidate.id === currentModeId) ?? modes[0]; diff --git a/packages/app/src/panels/agent-panel.tsx b/packages/app/src/panels/agent-panel.tsx index a9e11df570..7ae7d0c470 100644 --- a/packages/app/src/panels/agent-panel.tsx +++ b/packages/app/src/panels/agent-panel.tsx @@ -60,9 +60,8 @@ import { useContainerWidthBelow } from "@/hooks/use-container-width"; import { reconcileMissingAgentStateWithPresentAgent } from "@/panels/agent-panel-load-state"; import { TimelineSyncStatus } from "@/timeline/sync-status"; import { usePaneContext, usePaneFocus } from "@/panels/pane-context"; -import { buildAgentFactsLine } from "@/panels/agent-facts-line"; +import { useAgentFactsLine } from "@/panels/agent-facts-line"; import { PaneSubtitle } from "@/panels/pane-subtitle"; -import { useProvidersSnapshot } from "@/hooks/use-providers-snapshot"; import { definePanel, type PanelDescriptor } from "@/panels/panel-registry"; import { RenderProfile } from "@/utils/render-profiler"; import { useHasPluginComposerPills } from "@/plugins"; @@ -1384,28 +1383,7 @@ function TimelineSyncErrorCallout({ * without its composer. */ function SheetAgentFacts({ serverId, agentId }: { serverId: string; agentId: string }) { - const agent = useSessionStore( - useShallow((state) => { - const current = state.sessions[serverId]?.agents.get(agentId); - return current - ? { - provider: current.provider, - cwd: current.cwd, - runtimeModelId: current.runtimeInfo?.model ?? null, - configuredModelId: current.model ?? null, - runtimeThinkingOptionId: current.runtimeInfo?.thinkingOptionId ?? null, - explicitThinkingOptionId: current.thinkingOptionId ?? null, - availableModes: current.availableModes, - currentModeId: current.currentModeId, - contextWindowUsedTokens: current.lastUsage?.contextWindowUsedTokens ?? null, - contextWindowMaxTokens: current.lastUsage?.contextWindowMaxTokens ?? null, - } - : null; - }), - ); - const { entries } = useProvidersSnapshot(serverId, { cwd: agent?.cwd }); - const models = entries?.find((entry) => entry.provider === agent?.provider)?.models ?? null; - const text = agent ? buildAgentFactsLine({ ...agent, models }) : null; + const text = useAgentFactsLine(serverId, agentId); return text ? : null; } diff --git a/packages/app/src/panels/setup-panel.tsx b/packages/app/src/panels/setup-panel.tsx index 3648bf5a1c..7330c513ae 100644 --- a/packages/app/src/panels/setup-panel.tsx +++ b/packages/app/src/panels/setup-panel.tsx @@ -1,7 +1,7 @@ import { LoadingSpinner } from "@/components/ui/loading-spinner"; import { Alert } from "@/components/ui/alert"; import { Button } from "@/components/ui/button"; -import { useCallback, useEffect, useMemo, useRef, useState } from "react"; +import { useCallback, useEffect, useMemo, useState } from "react"; import { CheckCircle2, ChevronRight, CircleAlert, SquareTerminal } from "lucide-react-native"; import { useTranslation } from "react-i18next"; import { Pressable, type PressableStateCallbackType, ScrollView, Text, View } from "react-native"; @@ -17,6 +17,9 @@ import { type WorkspaceSetupSnapshot, } from "@/stores/workspace-setup-store"; import { useHostRuntimeClient } from "@/runtime/host-runtime"; +import { useWorkspaceFields } from "@/stores/session-store-hooks"; +import { useRetainedPanelActive } from "@/components/retained-panel"; +import { useAppActivelyVisible } from "@/hooks/use-app-visible"; import { useHostFeature } from "@/runtime/host-features"; function useSetupPanelDescriptor( @@ -24,13 +27,11 @@ function useSetupPanelDescriptor( context: { serverId: string; workspaceId: string }, ): PanelDescriptor { const { t } = useTranslation(); - const key = buildWorkspaceTabPersistenceKey({ - serverId: context.serverId, - workspaceId: target.workspaceId, - }); - const snapshot = useWorkspaceSetupStore((state) => (key ? (state.snapshots[key] ?? null) : null)); + const fields = useWorkspaceFields(context.serverId, target.workspaceId, (workspace) => ({ + status: workspace.setupStatus ?? null, + })); - if (snapshot?.status === "completed") { + if (fields?.status === "completed") { return { label: t("workspace.setup.descriptor.label"), subtitle: t("workspace.setup.descriptor.completed"), @@ -41,7 +42,7 @@ function useSetupPanelDescriptor( }; } - if (snapshot?.status === "failed") { + if (fields?.status === "failed") { return { label: t("workspace.setup.descriptor.label"), subtitle: t("workspace.setup.descriptor.failed"), @@ -52,7 +53,7 @@ function useSetupPanelDescriptor( }; } - if (snapshot?.status === "blocked") { + if (fields?.status === "blocked") { return { label: t("workspace.setup.descriptor.label"), subtitle: t("workspace.setup.descriptor.blocked"), @@ -69,7 +70,7 @@ function useSetupPanelDescriptor( tooltip: t("workspace.setup.descriptor.workspace"), titleState: "ready", icon: SquareTerminal, - statusBucket: snapshot?.status === "running" ? "running" : null, + statusBucket: fields?.status === "running" ? "running" : null, }; } @@ -216,33 +217,34 @@ function buildCommandRowState(args: BuildCommandRowPropsArgs) { return { hasError, hasLog, isExpandable, isAutoExpanded, showDetail, processedLog }; } -function useWorkspaceSetupSnapshot(serverId: string, workspaceId: string) { +function useWorkspaceSetupSnapshot(serverId: string, workspaceId: string, enabled: boolean) { const client = useHostRuntimeClient(serverId); const key = buildWorkspaceTabPersistenceKey({ serverId, workspaceId }); const snapshot = useWorkspaceSetupStore((state) => (key ? (state.snapshots[key] ?? null) : null)); - const upsertProgress = useWorkspaceSetupStore((state) => state.upsertProgress); - const requestedRef = useRef(false); - + const applySnapshot = useWorkspaceSetupStore((state) => state.applySnapshot); + const [error, setError] = useState(null); useEffect(() => { - if (snapshot || requestedRef.current || !client) return; - requestedRef.current = true; - client - .fetchWorkspaceSetupStatus(workspaceId) - .then((response) => { - if (response.snapshot) { - upsertProgress({ - serverId, - payload: { workspaceId: response.workspaceId, ...response.snapshot }, - }); - } - return; - }) - .catch(() => { - // Server may not support this yet — ignore. - }); - }, [client, snapshot, serverId, upsertProgress, workspaceId]); - - return snapshot; + if (!client || !enabled) return; + setError(null); + const subscription = client.observeWorkspaceSetup(workspaceId); + const detach = subscription.subscribe({ + snapshot: (response) => { + applySnapshot({ serverId, workspaceId, snapshot: response.snapshot }); + }, + update: (message) => { + if (message.type === "workspace_setup_progress") + applySnapshot({ serverId, workspaceId, snapshot: message.payload }); + }, + error: (failure) => setError(failure instanceof Error ? failure.message : String(failure)), + }); + return () => { + detach(); + void subscription + .release() + .catch((failure) => console.warn("Failed to release setup observation", failure)); + }; + }, [client, enabled, serverId, applySnapshot, workspaceId]); + return { snapshot, error }; } function useExpandedSetupCommands() { @@ -273,7 +275,14 @@ function SetupPanel() { const { serverId, target } = usePaneContext(); invariant(target.kind === "setup", "SetupPanel requires setup target"); - const snapshot = useWorkspaceSetupSnapshot(serverId, target.workspaceId); + const isActive = useRetainedPanelActive(); + const isVisible = useAppActivelyVisible(); + const supportsObservation = useHostFeature(serverId, "workspaceSetupObservation"); + const { snapshot, error: observationError } = useWorkspaceSetupSnapshot( + serverId, + target.workspaceId, + isActive && isVisible && supportsObservation, + ); const commands = snapshot?.detail.commands ?? EMPTY_COMMANDS; const log = snapshot?.detail.log ?? ""; @@ -306,19 +315,23 @@ function SetupPanel() { {statusLabel} - + {!supportsObservation && } + {observationError && } + {supportsObservation && !observationError && ( + + )} ); } diff --git a/packages/app/src/plugins/attachments/model.ts b/packages/app/src/plugins/attachments/model.ts index 29798b2d31..eef5665e71 100644 --- a/packages/app/src/plugins/attachments/model.ts +++ b/packages/app/src/plugins/attachments/model.ts @@ -1,6 +1,10 @@ import { z } from "zod"; import type { AgentAttachment } from "@getpaseo/protocol/messages"; -import { PluginAttachmentItemSchema, type PluginAttachmentItem } from "@getpaseo/plugin"; +import { + PluginAttachmentItemSchema, + type PluginAttachmentItem, + type PluginSerializableIcon, +} from "@getpaseo/plugin"; import type { UserComposerAttachment } from "@/attachments/types"; export const PluginResourceComposerAttachmentSchema = z.object({ @@ -8,7 +12,8 @@ export const PluginResourceComposerAttachmentSchema = z.object({ pluginId: z.string().min(1), sourceId: z.string().min(1), sourceTitle: z.string().min(1), - sourceIcon: z.string().min(1), + // Validated when the source registered; a draft keeps the icon its source had then. + sourceIcon: z.union([z.string().min(1), z.object({ svg: z.string().min(1) })]), item: PluginAttachmentItemSchema, }); @@ -20,7 +25,7 @@ export interface PluginResourceSourceIdentity { pluginId: string; sourceId: string; sourceTitle: string; - sourceIcon: string; + sourceIcon: PluginSerializableIcon; } export function createPluginResourceAttachment( diff --git a/packages/app/src/plugins/attachments/picker.tsx b/packages/app/src/plugins/attachments/picker.tsx index a63c1eb4e0..606fba5885 100644 --- a/packages/app/src/plugins/attachments/picker.tsx +++ b/packages/app/src/plugins/attachments/picker.tsx @@ -2,15 +2,18 @@ import { useCallback, useMemo, useState, type ReactElement, type RefObject } fro import { View } from "react-native"; import { withUnistyles } from "react-native-unistyles"; import type { DaemonClient } from "@getpaseo/client/internal/daemon-client"; -import type { PluginAttachmentItem, PluginAttachmentSourceContribution } from "@getpaseo/plugin"; +import type { + PluginAttachmentItem, + PluginAttachmentSourceContribution, + PluginSerializableIcon, +} from "@getpaseo/plugin"; import { searchPluginAttachments } from "@getpaseo/plugin/client/host"; -import type { LucideIcon } from "lucide-react-native"; import type { UserComposerAttachment } from "@/attachments/types"; import type { AttachmentMenuItem } from "@/composer/input/input"; import { Combobox, type ComboboxOption } from "@/components/ui/combobox"; import { useFetchQuery } from "@/data/query"; import { ICON_SIZE, type Theme } from "@/styles/theme"; -import { resolvePluginIcon } from "../icons"; +import { PluginIconView } from "../icons"; import { useInstalledPlugins } from "../registry"; import type { InstalledPlugin } from "../types"; import { createPluginResourceAttachment, togglePluginResourceAttachment } from "./model"; @@ -19,8 +22,8 @@ const SEARCH_STALE_TIME_MS = 30_000; const EMPTY_ATTACHMENT_ITEMS: PluginAttachmentItem[] = []; const iconColorMapping = (theme: Theme) => ({ color: theme.colors.foregroundMuted }); -function SourceIcon({ Icon, color = "" }: { Icon: LucideIcon; color?: string }) { - return ; +function SourceIcon({ icon, color = "" }: { icon: PluginSerializableIcon; color?: string }) { + return ; } const ThemedSourceIcon = withUnistyles(SourceIcon); @@ -145,15 +148,12 @@ export function usePluginAttachmentPicker( ); const menuItems = useMemo( () => - sources.map(({ key, source }) => { - const Icon = resolvePluginIcon(source.icon); - return { - id: `plugin:${key}`, - label: `Attach ${source.title}`, - icon: , - onSelect: () => setActiveKey(key), - }; - }), + sources.map(({ key, source }) => ({ + id: `plugin:${key}`, + label: `Attach ${source.title}`, + icon: , + onSelect: () => setActiveKey(key), + })), [sources], ); if (!active) return { menuItems, picker: null }; diff --git a/packages/app/src/plugins/attachments/pill.tsx b/packages/app/src/plugins/attachments/pill.tsx index 18fb926b59..774a7d359d 100644 --- a/packages/app/src/plugins/attachments/pill.tsx +++ b/packages/app/src/plugins/attachments/pill.tsx @@ -3,19 +3,14 @@ import { withUnistyles } from "react-native-unistyles"; import { AttachmentLabel, AttachmentPill } from "@/components/attachment-pill"; import type { ComposerAttachment } from "@/attachments/types"; import { ICON_SIZE, type Theme } from "@/styles/theme"; -import { resolvePluginIcon } from "../icons"; +import type { PluginSerializableIcon } from "@getpaseo/plugin"; +import { PluginIconView } from "../icons"; import type { PluginResourceComposerAttachment } from "./model"; const iconColorMapping = (theme: Theme) => ({ color: theme.colors.foregroundMuted }); -function ResourceIcon({ - Icon, - color = "", -}: { - Icon: ReturnType; - color?: string; -}) { - return ; +function ResourceIcon({ icon, color = "" }: { icon: PluginSerializableIcon; color?: string }) { + return ; } const ThemedResourceIcon = withUnistyles(ResourceIcon); @@ -39,12 +34,11 @@ export function PluginResourceAttachmentPill({ openLabel, removeLabel, }: PluginResourceAttachmentPillProps) { - const Icon = resolvePluginIcon(attachment.sourceIcon); const handleOpen = useCallback(() => onOpen(attachment), [attachment, onOpen]); const handleRemove = useCallback(() => onRemove(index), [index, onRemove]); const icon = useMemo( - () => , - [Icon], + () => , + [attachment.sourceIcon], ); return ( parsePluginIcon("Plugin button", icon), +}); diff --git a/packages/app/src/plugins/buttons/validation.ts b/packages/app/src/plugins/buttons/validation.ts index 650c21fac2..72e656a271 100644 --- a/packages/app/src/plugins/buttons/validation.ts +++ b/packages/app/src/plugins/buttons/validation.ts @@ -1,7 +1,8 @@ import type { PluginButton, PluginButtonBehavior, PluginButtonIcon } from "@getpaseo/plugin/client"; export interface ButtonValidation { - validateIconName(name: string): void; + /** Returns the normalized icon, or throws naming why the icon is unusable. */ + parseIcon(icon: PluginButtonIcon): PluginButtonIcon; } export function requireButtonId(value: string): string { @@ -29,12 +30,6 @@ function isComponent(value: unknown): boolean { ); } -function validateIcon(icon: PluginButtonIcon, validation: ButtonValidation): void { - if (typeof icon === "string") validation.validateIconName(icon); - else if (!isComponent(icon)) - throw new Error("Plugin button icon must be a Lucide name or component"); -} - function validateBehavior( behavior: PluginButtonBehavior, validation: ButtonValidation, @@ -57,9 +52,9 @@ function validateBehavior( ids.add(item.id); if (item.kind === "separator") return { ...item }; if (item.kind !== "item") throw new Error("Invalid plugin button menu entry"); - if (item.icon !== undefined) validateIcon(item.icon, validation); return { ...item, + icon: item.icon === undefined ? undefined : validation.parseIcon(item.icon), title: requireText(item.title, "menu item title"), visible: optionalBoolean(item.visible, true), disabled: optionalBoolean(item.disabled, false), @@ -83,9 +78,9 @@ export function validateButton( button: PluginButton, validation: ButtonValidation, ): ResolvedPluginButton { - validateIcon(button.icon, validation); return { ...button, + icon: validation.parseIcon(button.icon), title: requireText(button.title, "title"), label: button.label === undefined ? undefined : requireText(button.label, "label"), visible: optionalBoolean(button.visible, true), diff --git a/packages/app/src/plugins/buttons/view.tsx b/packages/app/src/plugins/buttons/view.tsx index 7eae9a046d..1a092c6cf1 100644 --- a/packages/app/src/plugins/buttons/view.tsx +++ b/packages/app/src/plugins/buttons/view.tsx @@ -32,7 +32,7 @@ import { useToast } from "@/contexts/toast-context"; import { useHostRuntimeClient, useHosts } from "@/runtime/host-runtime"; import type { Theme } from "@/styles/theme"; import { createPluginClientStateSource } from "../client-state/source"; -import { Icon } from "../icons"; +import { pluginIconComponent } from "../icons"; import { PluginEnvironmentProvider, PluginPopoverContent, @@ -79,6 +79,7 @@ function ButtonEnvironment({ view, children }: { view: ButtonView; children: Rea function ButtonIcon({ view, icon }: { view: ButtonView; icon: PluginButtonIcon }) { const color = view.props.theme.colors.foregroundMuted; const size = view.entry.placement === "composer" ? 14 : 16; + const Icon = pluginIconComponent(icon); return ( - {typeof icon === "string" ? ( - - ) : ( - renderCustomIcon(icon, view, size, color) - )} + ); } -function renderCustomIcon( - CustomIcon: Exclude, - view: ButtonView, - size: number, - color: string, -) { - return ; -} - function pressButton(view: ButtonView, path: readonly string[]) { void pluginButtonStore.run(view.entry.key, path).catch((error: unknown) => { view.toast.error(error instanceof Error ? error.message : String(error)); diff --git a/packages/app/src/plugins/command-center/contributions.ts b/packages/app/src/plugins/command-center/contributions.ts index be4cb8068a..400e2ded86 100644 --- a/packages/app/src/plugins/command-center/contributions.ts +++ b/packages/app/src/plugins/command-center/contributions.ts @@ -1,7 +1,7 @@ import type { PluginClientStateSource } from "@getpaseo/plugin/client/host"; import type { CommandCenterContribution } from "@/command-center/contributions"; import { getCommandCenterIcon } from "@/command-center/icon"; -import { resolvePluginIcon } from "../icons"; +import { pluginIconComponent } from "../icons"; import { resolvePluginPanelOpenLocation } from "../workspace-panels/locations"; import type { InstalledPlugin } from "../types"; import { createPluginCapabilities, type PluginNavigation } from "../actions"; @@ -83,7 +83,7 @@ export function buildPluginCommandCenterContributions( kind: "action", title: item.title, sectionTitle: plugin.id, - icon: getCommandCenterIcon(resolvePluginIcon(item.icon)), + icon: getCommandCenterIcon(pluginIconComponent(item.icon)), }, run, }); diff --git a/packages/app/src/plugins/evaluate.test.ts b/packages/app/src/plugins/evaluate.test.ts index 310ef5f7b9..cf9b4e049c 100644 --- a/packages/app/src/plugins/evaluate.test.ts +++ b/packages/app/src/plugins/evaluate.test.ts @@ -381,6 +381,72 @@ describe("evaluatePluginClientBundle", () => { ).toEqual([{ id: "open-review", title: "Open review", icon: "Scan", context: "agent" }]); }); + it("registers inline SVG and component icons", () => { + const svg = ''; + const plugin = evaluatePluginClientBundle( + "review", + bundle(` + function ReviewPanel() { return null; } + function BadgeIcon() { return null; } + plugin.addWorkspacePanel({ + id: "review", + title: "Review", + icon: { svg: ${JSON.stringify(` ${svg}\n`)} }, + context: "workspace", + Component: ReviewPanel, + }); + plugin.addCommandCenterItem({ + id: "open-review", + title: "Open review", + icon: BadgeIcon, + context: "global", + onSelect() {}, + }); + plugin.addAttachmentSource({ + id: "issues", + title: "Issues", + icon: { svg: ${JSON.stringify(svg)} }, + pickerTitle: "Attach issue", + searchPlaceholder: "Search", + search: { name: "issues.search", input: {}, output: {} }, + }); + `), + ); + + expect(plugin.workspacePanels[0]?.icon).toEqual({ svg }); + expect(plugin.commandCenterItems[0]?.icon).toHaveProperty("name", "BadgeIcon"); + expect(plugin.attachmentSources[0]?.icon).toEqual({ svg }); + }); + + it.each([ + [ + "workspace panel", + `plugin.addWorkspacePanel({ id: "review", title: "Review", icon: ICON, context: "workspace", Component() { return null; } })`, + "Workspace panel review has an invalid icon: script elements are not allowed", + ], + [ + "Command Center item", + `plugin.addCommandCenterItem({ id: "review", title: "Review", icon: ICON, context: "global", onSelect() {} })`, + "Command Center item review has an invalid icon: script elements are not allowed", + ], + [ + "settings screen", + `plugin.addSettingsScreen({ id: "review", title: "Review", icon: ICON, Component() { return null; } })`, + "Settings screen review has an invalid icon: script elements are not allowed", + ], + [ + "attachment source", + `plugin.addAttachmentSource({ id: "review", title: "Review", icon: ICON, pickerTitle: "Pick", searchPlaceholder: "Search", search: { name: "issues.search", input: {}, output: {} } })`, + "Attachment source review has an invalid icon: script elements are not allowed", + ], + ])("fails the plugin when a %s registers an unsafe SVG", (_kind, registration, message) => { + const icon = JSON.stringify({ svg: "" }); + + expect(() => + evaluatePluginClientBundle("review", bundle(registration.replace("ICON", icon))), + ).toThrow(message); + }); + it("normalizes and validates workspace panel locations", () => { const plugin = evaluatePluginClientBundle( "review", diff --git a/packages/app/src/plugins/evaluate.ts b/packages/app/src/plugins/evaluate.ts index a2703b6ad2..a7d3f04793 100644 --- a/packages/app/src/plugins/evaluate.ts +++ b/packages/app/src/plugins/evaluate.ts @@ -33,7 +33,7 @@ import { } from "@getpaseo/plugin/client"; import type { EvaluatedPlugin, PluginSidebarSection } from "./types"; import type { ComponentType } from "react"; -import { resolvePluginIcon } from "./icons"; +import { parsePluginIcon, parseSerializablePluginIcon } from "./icons"; import { pluginReactNativeRuntime } from "./react-native/runtime"; import { parsePluginThemeContribution } from "./themes"; @@ -199,9 +199,9 @@ export function runPluginClientBundle( if (settingsScreenIds.has(screenId)) throw new Error(`Duplicate settings screen: ${screenId}`); if (!contribution.title.trim()) throw new Error(`Invalid settings screen: ${screenId}`); - resolvePluginIcon(contribution.icon); + const icon = parsePluginIcon(`Settings screen ${screenId}`, contribution.icon); settingsScreenIds.add(screenId); - return register(collector.settingsScreens, { ...contribution, id: screenId }, () => + return register(collector.settingsScreens, { ...contribution, id: screenId, icon }, () => settingsScreenIds.delete(screenId), ); }, @@ -241,12 +241,10 @@ export function runPluginClientBundle( // COMPAT(pluginSidebarAliases): added in v0.11.0, remove after 2027-03-29 addSidebarItem(contribution: PluginSidebarContribution) { const normalizedId = requireId(contribution.id, "sidebar item id"); - if (!contribution.icon.trim()) throw new Error(`Sidebar item ${normalizedId} has no icon`); - resolvePluginIcon(contribution.icon.trim()); const legacy = { id: normalizedId, title: contribution.title.trim(), - icon: contribution.icon.trim(), + icon: parsePluginIcon(`Sidebar item ${normalizedId}`, contribution.icon), surface: requireId(contribution.surface, "sidebar surface id"), }; // Shares the header's ids: the sidebar orders both kinds of item under one key. @@ -262,16 +260,14 @@ export function runPluginClientBundle( throw new Error(`Duplicate workspace panel: ${normalizedId}`); } const title = contribution.title.trim(); - const icon = contribution.icon.trim(); if (!title) throw new Error(`Workspace panel ${normalizedId} has no title`); - if (!icon) throw new Error(`Workspace panel ${normalizedId} has no icon`); + const icon = parsePluginIcon(`Workspace panel ${normalizedId}`, contribution.icon); if (contribution.context !== "workspace" && contribution.context !== "agent") { throw new Error(`Workspace panel ${normalizedId} has invalid context`); } if (typeof contribution.Component !== "function") { throw new Error(`Workspace panel ${normalizedId} is not a component`); } - resolvePluginIcon(icon); const locations = normalizePanelLocations(normalizedId, contribution.locations); workspacePanelIds.add(normalizedId); return register( @@ -292,9 +288,8 @@ export function runPluginClientBundle( throw new Error(`Duplicate Command Center item: ${normalizedId}`); } const title = contribution.title.trim(); - const icon = contribution.icon.trim(); if (!title) throw new Error(`Command Center item ${normalizedId} has no title`); - if (!icon) throw new Error(`Command Center item ${normalizedId} has no icon`); + const icon = parsePluginIcon(`Command Center item ${normalizedId}`, contribution.icon); if ( contribution.context !== "global" && contribution.context !== "workspace" && @@ -305,7 +300,6 @@ export function runPluginClientBundle( if (typeof contribution.onSelect !== "function") { throw new Error(`Command Center item ${normalizedId} has no callback`); } - resolvePluginIcon(icon); commandCenterItemIds.add(normalizedId); return register( collector.commandCenterItems, @@ -350,18 +344,19 @@ export function runPluginClientBundle( throw new Error(`Duplicate attachment source: ${normalizedId}`); } const title = contribution.title.trim(); - const icon = contribution.icon.trim(); const pickerTitle = contribution.pickerTitle.trim(); const searchPlaceholder = contribution.searchPlaceholder.trim(); const method = contribution.search.name.trim(); if (!title) throw new Error(`Attachment source ${normalizedId} has no title`); - if (!icon) throw new Error(`Attachment source ${normalizedId} has no icon`); + const icon = parseSerializablePluginIcon( + `Attachment source ${normalizedId}`, + contribution.icon, + ); if (!pickerTitle) throw new Error(`Attachment source ${normalizedId} has no picker title`); if (!searchPlaceholder) { throw new Error(`Attachment source ${normalizedId} has no search placeholder`); } if (!method) throw new Error(`Attachment source ${normalizedId} has no search RPC`); - resolvePluginIcon(icon); attachmentSourceIds.add(normalizedId); return register( collector.attachmentSources, diff --git a/packages/app/src/plugins/icons.test.ts b/packages/app/src/plugins/icons.test.ts deleted file mode 100644 index 4a4969d6fb..0000000000 --- a/packages/app/src/plugins/icons.test.ts +++ /dev/null @@ -1,18 +0,0 @@ -import { Settings } from "lucide-react-native"; -import { describe, expect, it } from "vitest"; -import { Icon } from "./icons"; - -describe("Icon", () => { - it("renders a host Lucide icon with the requested presentation", () => { - expect(Icon({ name: "Settings", size: 18, color: "#123456" })).toMatchObject({ - type: Settings, - props: { size: 18, color: "#123456" }, - }); - }); - - it("renders nothing for an unknown icon name", () => { - expect(Icon({ name: "NotALucideIcon" })).toBeNull(); - expect(Icon({ name: "Icon" })).toBeNull(); - expect(Icon({ name: "createLucideIcon" })).toBeNull(); - }); -}); diff --git a/packages/app/src/plugins/icons.test.tsx b/packages/app/src/plugins/icons.test.tsx new file mode 100644 index 0000000000..0fa189d137 --- /dev/null +++ b/packages/app/src/plugins/icons.test.tsx @@ -0,0 +1,104 @@ +import { Settings } from "lucide-react-native"; +import React, { isValidElement, type ReactElement, type ReactNode } from "react"; +import { SvgXml } from "react-native-svg"; +import { describe, expect, it } from "vitest"; +import type { PluginIconProps } from "@getpaseo/plugin"; +import { Icon, parsePluginIcon, parseSerializablePluginIcon, PluginIconView } from "./icons"; + +const SVG = ''; +const SVG_ICON = { svg: SVG }; + +const GLYPHS = new Set([Settings, SvgXml]); + +/** Expands function components down to what reaches the screen: a Lucide glyph, SvgXml, or DOM. */ +function draw(node: ReactNode): ReactElement | null { + if (!isValidElement(node)) return null; + const { type } = node; + if (typeof type !== "function" || GLYPHS.has(type)) return node; + return draw((type as (props: unknown) => ReactNode)(node.props)); +} + +function BadgeIcon({ size, color }: PluginIconProps) { + return ; +} + +describe("PluginIconView", () => { + it("draws a Lucide name as that Lucide icon", () => { + expect(draw()).toMatchObject({ + type: Settings, + props: { size: 18, color: "#123456" }, + }); + }); + + it("draws inline SVG sized to the surface, with color reaching currentColor", () => { + expect(draw()).toMatchObject({ + type: SvgXml, + props: { xml: SVG, width: 18, height: 18, color: "#123456" }, + }); + }); + + it("draws a component with the surface's size and color", () => { + expect(draw()).toMatchObject({ + type: "span", + props: { "data-size": 18, "data-color": "#123456" }, + }); + }); +}); + +describe("parsePluginIcon", () => { + it("normalizes each icon form", () => { + expect(parsePluginIcon("Workspace panel files", " Settings ")).toBe("Settings"); + expect(parsePluginIcon("Workspace panel files", { svg: `\n${SVG}\n` })).toEqual({ svg: SVG }); + expect(parsePluginIcon("Workspace panel files", BadgeIcon)).toBe(BadgeIcon); + }); + + it.each([ + ["", "Workspace panel files has no icon"], + [ + "NotALucideIcon", + 'Workspace panel files has an invalid icon: unknown Lucide icon "NotALucideIcon"', + ], + [ + { svg: "" }, + "Workspace panel files has an invalid icon: script elements are not allowed", + ], + [{ svg: "hello" }, "Workspace panel files has an invalid icon: not an SVG document"], + [ + { path: "icon.svg" }, + "Workspace panel files has an invalid icon: expected a Lucide icon name, { svg }, or a component", + ], + ])("rejects %j", (icon, message) => { + expect(() => parsePluginIcon("Workspace panel files", icon as never)).toThrow(message); + }); + + it("refuses a component where the icon is stored as data", () => { + expect(() => + parseSerializablePluginIcon("Attachment source issues", BadgeIcon as never), + ).toThrow( + "Attachment source issues has an invalid icon: expected a Lucide icon name or { svg }", + ); + }); +}); + +describe("Icon", () => { + it("renders a host Lucide icon by name with the requested presentation", () => { + expect(draw(Icon({ name: "Settings", size: 18, color: "#123456" }))).toMatchObject({ + type: Settings, + props: { size: 18, color: "#123456" }, + }); + }); + + it("renders a plugin's own SVG through the icon prop", () => { + expect(draw(Icon({ icon: { svg: SVG }, size: 18, color: "#123456" }))).toMatchObject({ + type: SvgXml, + props: { xml: SVG, width: 18, color: "#123456" }, + }); + }); + + it("renders nothing for an unusable icon", () => { + expect(Icon({ name: "NotALucideIcon" })).toBeNull(); + expect(Icon({ name: "Icon" })).toBeNull(); + expect(Icon({ name: "createLucideIcon" })).toBeNull(); + expect(Icon({ icon: { svg: '' } })).toBeNull(); + }); +}); diff --git a/packages/app/src/plugins/icons.ts b/packages/app/src/plugins/icons.ts index 3c5ec581ce..ba67d8fa35 100644 --- a/packages/app/src/plugins/icons.ts +++ b/packages/app/src/plugins/icons.ts @@ -1,24 +1,150 @@ -import { createElement, type ReactElement } from "react"; +import { createElement, type ComponentType, type ReactElement } from "react"; import * as LucideIcons from "lucide-react-native"; -import type { PluginIconProps } from "@getpaseo/plugin/client"; import type { LucideIcon } from "lucide-react-native"; +import { + findSvgIconProblem, + type PluginIconProps, + type PluginSerializableIcon, + type PluginSvgIcon, +} from "@getpaseo/plugin"; +import type { PluginIcon } from "@getpaseo/plugin/client"; +import type { IconProps } from "@getpaseo/plugin/client/react-native"; +import { SvgIcon } from "@/components/provider-icons"; -function findPluginIcon(name: string): LucideIcon | null { +/** Host surfaces may thin a Lucide stroke; SVG and plugin components ignore it. */ +type HostIconProps = PluginIconProps & { strokeWidth?: number }; +/** A host-drawn icon. A plain function, so it stands in for any plugin icon component type. */ +type HostIcon = (props: HostIconProps) => ReactElement | null; + +const lucideIconComponents = new Map(); +const svgIconComponents = new Map(); + +function findLucideIcon(name: string): LucideIcon | null { const candidate = Reflect.get(LucideIcons, name); if (candidate === LucideIcons.Icon || candidate === LucideIcons.createLucideIcon) return null; - const isComponent = - typeof candidate === "function" || - (typeof candidate === "object" && candidate !== null && "$$typeof" in candidate); - return isComponent ? (candidate as LucideIcon) : null; + return isComponent(candidate) ? (candidate as LucideIcon) : null; } -export function resolvePluginIcon(name: string): LucideIcon { - const icon = findPluginIcon(name); - if (!icon) throw new Error(`Unknown Lucide icon: ${name}`); +function isComponent(value: unknown): boolean { + return ( + typeof value === "function" || + (typeof value === "object" && value !== null && "$$typeof" in value) + ); +} + +function isSvgIcon(icon: unknown): icon is PluginSvgIcon { + return ( + typeof icon === "object" && + icon !== null && + !("$$typeof" in icon) && + typeof Reflect.get(icon, "svg") === "string" + ); +} + +function isComponentIcon( + icon: PluginIcon, +): icon is ComponentType { + return isComponent(icon); +} + +function invalidIcon(owner: string, reason: string): Error { + return new Error(`${owner} has an invalid icon: ${reason}`); +} + +/** Validates an icon that is stored with the data it labels. Returns the normalized icon. */ +export function parseSerializablePluginIcon( + owner: string, + icon: PluginSerializableIcon, +): PluginSerializableIcon { + if (typeof icon === "string") { + const name = icon.trim(); + if (!name) throw new Error(`${owner} has no icon`); + if (!findLucideIcon(name)) throw invalidIcon(owner, `unknown Lucide icon "${name}"`); + return name; + } + if (!isSvgIcon(icon)) throw invalidIcon(owner, "expected a Lucide icon name or { svg }"); + const svg = icon.svg.trim(); + const problem = findSvgIconProblem(svg); + if (problem) throw invalidIcon(owner, problem); + return { svg }; +} + +/** Validates a contribution's icon once, at registration. Rendering trusts the result. */ +export function parsePluginIcon( + owner: string, + icon: PluginIcon, +): PluginIcon { + if (isComponentIcon(icon)) return icon; + if (typeof icon !== "string" && !isSvgIcon(icon)) { + throw invalidIcon(owner, "expected a Lucide icon name, { svg }, or a component"); + } + return parseSerializablePluginIcon(owner, icon); +} + +function MissingIcon(): null { + return null; +} + +function createLucideIcon(name: string, Lucide: LucideIcon): HostIcon { + function PluginLucideIcon({ size, color, strokeWidth }: HostIconProps) { + return createElement(Lucide, { size, color, strokeWidth }); + } + PluginLucideIcon.displayName = `PluginLucideIcon(${name})`; + return PluginLucideIcon; +} + +function lucideIconComponent(name: string): HostIcon { + const cached = lucideIconComponents.get(name); + if (cached) return cached; + const Lucide = findLucideIcon(name); + if (!Lucide) return MissingIcon; + const icon = createLucideIcon(name, Lucide); + lucideIconComponents.set(name, icon); return icon; } -export function Icon({ name, size, color }: PluginIconProps): ReactElement | null { - const icon = findPluginIcon(name); - return icon ? createElement(icon, { size, color }) : null; +function svgIconComponent(svg: string): HostIcon { + const cached = svgIconComponents.get(svg); + if (cached) return cached; + function PluginSvgIcon({ size, color }: PluginIconProps) { + return createElement(SvgIcon, { svg, size, color }); + } + svgIconComponents.set(svg, PluginSvgIcon); + return PluginSvgIcon; +} + +/** + * A stable component for a registered icon, for surfaces that take an icon component. Lucide and + * SVG icons draw from `size` and `color` only; a plugin component receives every prop. + */ +export function pluginIconComponent( + icon: PluginIcon, +): ComponentType { + if (typeof icon === "string") return lucideIconComponent(icon); + if (isSvgIcon(icon)) return svgIconComponent(icon.svg); + return icon; +} + +export interface PluginIconViewProps extends PluginIconProps { + icon: PluginIcon; +} + +/** Draws a registered plugin icon. `color` tints Lucide icons and `currentColor` in SVG. */ +export function PluginIconView({ icon, size, color }: PluginIconViewProps): ReactElement { + return createElement(pluginIconComponent(icon), { size, color }); +} + +function isRenderable(icon: PluginIcon): boolean { + if (typeof icon === "string") return findLucideIcon(icon) !== null; + if (isSvgIcon(icon)) return findSvgIconProblem(icon.svg) === null; + return isComponent(icon); +} + +/** The kit `Icon`. Plugin code passes it anything, so an unusable icon renders nothing. */ +export function Icon(props: IconProps): ReactElement | null { + const icon = props.icon === undefined ? props.name : props.icon; + if (!isRenderable(icon)) return null; + const size = props.size ?? 24; + const color = props.color ?? "currentColor"; + return createElement(PluginIconView, { icon, size, color }); } diff --git a/packages/app/src/plugins/sidebar-groups.ts b/packages/app/src/plugins/sidebar-groups.ts index c764a53dcc..2d4411acad 100644 --- a/packages/app/src/plugins/sidebar-groups.ts +++ b/packages/app/src/plugins/sidebar-groups.ts @@ -9,6 +9,7 @@ import type { PluginSidebarItemContribution, PluginSidebarSection, } from "./types"; +import type { PluginIcon } from "@getpaseo/plugin/client"; export interface PluginSidebarTarget { plugin: InstalledPlugin; @@ -36,7 +37,7 @@ export type PluginSidebarGroup = | (PluginSidebarGroupBase & { kind: "item"; targets: PluginSidebarTarget[] }) | (PluginSidebarGroupBase & { kind: "legacy"; - icon: string; + icon: PluginIcon; targets: PluginLegacySidebarTarget[]; }); diff --git a/packages/app/src/plugins/sidebar-items/kit.tsx b/packages/app/src/plugins/sidebar-items/kit.tsx index 5796d572ca..6b29cbea42 100644 --- a/packages/app/src/plugins/sidebar-items/kit.tsx +++ b/packages/app/src/plugins/sidebar-items/kit.tsx @@ -1,16 +1,12 @@ -import type { SidebarIcon, SidebarRowProps } from "@getpaseo/plugin/client/ui"; -import { useCallback, useEffect, useRef } from "react"; +import type { SidebarRowProps } from "@getpaseo/plugin/client/ui"; +import { useCallback, useEffect, useMemo, useRef } from "react"; import { View } from "react-native"; import { StyleSheet } from "react-native-unistyles"; import { SidebarHeaderRow } from "@/components/sidebar/sidebar-header-row"; import { SidebarSeparator as AppSidebarSeparator } from "@/components/sidebar/sidebar-separator"; -import { resolvePluginIcon } from "../icons"; +import { parsePluginIcon, pluginIconComponent } from "../icons"; import { useSidebarItemFrame } from "./frame"; -function resolveIcon(icon: SidebarIcon) { - return typeof icon === "string" ? resolvePluginIcon(icon) : icon; -} - /** * An item may render several rows. Any press inside a row, on the row or on its trailing content, * makes that row the popover anchor: the capture-phase responder check runs before the pressed @@ -29,6 +25,11 @@ export function SidebarRow({ id, icon, label, onPress, active, trailing }: Sideb anchorTo(rowRef.current); return false; }, [anchorTo]); + // Rows get their icon at render, not registration, so an invalid icon throws to the item's boundary. + const iconComponent = useMemo( + () => (icon ? pluginIconComponent(parsePluginIcon("Sidebar row", icon)) : null), + [icon], + ); // Keyboard activation skips the responder system, so the row's own press anchors as well. const handlePress = useCallback(() => { anchorTo(rowRef.current); @@ -37,7 +38,7 @@ export function SidebarRow({ id, icon, label, onPress, active, trailing }: Sideb return ( ; - color?: string; -}) { - return ; +function PluginHeaderIcon({ icon, color = "" }: { icon: PluginIcon; color?: string }) { + return ; } const ThemedPluginHeaderIcon = withUnistyles(PluginHeaderIcon); @@ -162,7 +156,7 @@ export function PluginSurfaceScreen() { : (sidebarItem?.title ?? (pluginId || "Plugin")), [params, pluginId, sidebarItem, surface], ); - const Icon = sidebarItem ? resolvePluginIcon(sidebarItem.icon) : null; + const icon = sidebarItem?.icon ?? null; const close = useCallback(() => { if (router.canGoBack()) router.back(); else router.replace(`/h/${encodeURIComponent(serverId)}`); @@ -172,15 +166,15 @@ export function PluginSurfaceScreen() { const headerLeft = useMemo( () => ( <> - {Icon ? ( + {icon ? ( - + ) : null} {title} ), - [Icon, title], + [icon, title], ); const hostFilter = useMemo( () => diff --git a/packages/app/src/plugins/timeline/view.test.tsx b/packages/app/src/plugins/timeline/view.test.tsx index d915216105..ff3ba9fd6b 100644 --- a/packages/app/src/plugins/timeline/view.test.tsx +++ b/packages/app/src/plugins/timeline/view.test.tsx @@ -33,7 +33,7 @@ vi.mock("../client-runtime", () => ({ })); vi.mock("../icons", () => ({ Icon: () => null, - resolvePluginIcon: () => () => null, + pluginIconComponent: () => () => null, })); import { pluginRegistry } from "../registry"; diff --git a/packages/app/src/plugins/workspace-panels/panel.tsx b/packages/app/src/plugins/workspace-panels/panel.tsx index 998f7e90ff..48a83686be 100644 --- a/packages/app/src/plugins/workspace-panels/panel.tsx +++ b/packages/app/src/plugins/workspace-panels/panel.tsx @@ -17,7 +17,7 @@ import { normalizeWorkspaceOpaqueId } from "@/utils/workspace-identity"; import { usePluginHostNavigation } from "../host-navigation"; import { createPluginClientStateSource } from "../client-state/source"; import { toPluginTheme } from "../theme"; -import { resolvePluginIcon } from "../icons"; +import { pluginIconComponent } from "../icons"; import { useInstalledPlugin } from "../registry"; import { PluginInstallationProvider } from "../installation-provider"; import { SurfaceErrorBoundary } from "../surface-error-boundary"; @@ -144,7 +144,7 @@ function usePluginPanelDescriptor( subtitle: target.pluginId, tooltip: panel.title, titleState: "ready", - icon: resolvePluginIcon(panel.icon), + icon: pluginIconComponent(panel.icon), statusBucket: null, }; } diff --git a/packages/app/src/provider-selection/provider-selection.test.ts b/packages/app/src/provider-selection/provider-selection.test.ts index 6c13ad3d83..1c04c0b154 100644 --- a/packages/app/src/provider-selection/provider-selection.test.ts +++ b/packages/app/src/provider-selection/provider-selection.test.ts @@ -15,6 +15,21 @@ import { } from "./provider-selection"; describe("combined model selector data", () => { + it("shows a disconnected error for unfinished catalogs while keeping known models", () => { + const providers = buildSelectableProviderSelectorProviders( + [ + snapshotEntry({ provider: "waiting", status: "loading", models: [] }), + snapshotEntry({ provider: "codex", status: "ready", models: [codexModel] }), + ], + false, + ); + expect(providers[0].modelSelection).toEqual({ + kind: "error", + message: "Host is not connected", + }); + expect(providers[1].modelSelection.kind).toBe("models"); + }); + const codexModel: AgentModelDefinition = { provider: "codex", id: "gpt-5.4", @@ -367,7 +382,7 @@ describe("combined model selector data", () => { }, autoSubmitConfig: null, workspaceDirectory: "/repo", - hasClient: true, + isConnected: true, }), ).toEqual({ ok: false, @@ -387,7 +402,7 @@ describe("combined model selector data", () => { }, autoSubmitConfig: null, workspaceDirectory: "/repo", - hasClient: true, + isConnected: true, }), ).toEqual({ ok: true }); }); @@ -426,7 +441,7 @@ describe("combined model selector data", () => { }, autoSubmitConfig: null, workspaceDirectory: "/repo", - hasClient: true, + isConnected: true, }), ).toEqual({ ok: false, reason: "初始 prompt 必填" }); } finally { diff --git a/packages/app/src/provider-selection/provider-selection.ts b/packages/app/src/provider-selection/provider-selection.ts index f66a1b1476..e0313c6623 100644 --- a/packages/app/src/provider-selection/provider-selection.ts +++ b/packages/app/src/provider-selection/provider-selection.ts @@ -103,6 +103,7 @@ function buildModelSelection( function buildEntryModelSelection( entry: ProviderSnapshotEntry, label: string, + isConnected: boolean, ): ProviderModelSelection { if ((entry.models?.length ?? 0) > 0) { return buildModelSelection(entry.provider, label, entry.models ?? null); @@ -111,7 +112,9 @@ function buildEntryModelSelection( return buildModelSelection(entry.provider, label, entry.models ?? null); } if (entry.status === "loading") { - return { kind: "loading" }; + return isConnected + ? { kind: "loading" } + : { kind: "error", message: i18n.t("providerSelection.readiness.hostDisconnected") }; } return { kind: "error", @@ -142,6 +145,7 @@ export function buildProviderSelectorProviders(input: { export function buildSelectableProviderSelectorProviders( entries: ProviderSnapshotEntry[] | undefined, + isConnected = true, ): ProviderSelectorProvider[] { return (entries ?? []) .filter((entry) => entry.enabled) @@ -150,7 +154,7 @@ export function buildSelectableProviderSelectorProviders( return { id: entry.provider, label, - modelSelection: buildEntryModelSelection(entry, label), + modelSelection: buildEntryModelSelection(entry, label, isConnected), }; }); } @@ -345,11 +349,14 @@ export function resolveSubmissionReadiness(input: { }; autoSubmitConfig: { provider: string; model: string | null } | null; workspaceDirectory: string | null; - hasClient: boolean; + isConnected: boolean; }): ProviderSelectionReadiness { if (!input.allowsEmptyAutoSubmit && !input.text.trim()) { return { ok: false, reason: i18n.t("providerSelection.readiness.initialPromptRequired") }; } + if (!input.isConnected) { + return { ok: false, reason: i18n.t("providerSelection.readiness.hostDisconnected") }; + } if (input.providerCount === 0) { return { ok: false, reason: i18n.t("providerSelection.readiness.noProviders") }; } @@ -366,8 +373,5 @@ export function resolveSubmissionReadiness(input: { if (!input.workspaceDirectory) { return { ok: false, reason: i18n.t("providerSelection.readiness.workspaceDirectoryNotFound") }; } - if (!input.hasClient) { - return { ok: false, reason: i18n.t("providerSelection.readiness.hostDisconnected") }; - } return { ok: true }; } diff --git a/packages/app/src/runtime/directory-sync/workspace-replica.test.ts b/packages/app/src/runtime/directory-sync/workspace-replica.test.ts index 84f08b22fc..c9a674f3b3 100644 --- a/packages/app/src/runtime/directory-sync/workspace-replica.test.ts +++ b/packages/app/src/runtime/directory-sync/workspace-replica.test.ts @@ -10,6 +10,7 @@ import { clearWorkspaceArchivePending, markWorkspaceArchivePending, } from "@/contexts/session-workspace-upserts"; +import { useWorkspaceSetupStore } from "@/stores/workspace-setup-store"; import { WorkspaceDirectoryReplica } from "./workspace-replica"; function workspace(id: string, projectId = "project"): WorkspaceDescriptorPayload { @@ -230,3 +231,38 @@ it("does not restore a targeted cached workspace while its archive is pending", store.clearSession(serverId); } }); + +it("setup metadata from directory snapshots and transitions resets failure surfacing without details", () => { + const serverId = "setup-metadata"; + useSessionStore.getState().initializeSession(serverId, null as unknown as DaemonClient); + const replica = new WorkspaceDirectoryReplica(serverId); + const identity = { serverId, workspaceId: "setup" }; + const store = useWorkspaceSetupStore.getState(); + replica.commitSnapshot( + { + workspaces: new Map([ + ["setup", normalizeWorkspaceDescriptor({ ...workspace("setup"), setupStatus: "blocked" })], + ]), + projects: new Map(), + }, + [], + ); + expect(useSessionStore.getState().sessions[serverId].workspaces.get("setup")?.setupStatus).toBe( + "blocked", + ); + expect(store.claimFailedSetupSurface({ ...identity, status: "blocked" })).toBe(true); + replica.applyDelta({ + kind: "upsert", + workspace: { ...workspace("setup"), setupStatus: "running" }, + }); + replica.applyDelta({ + kind: "upsert", + workspace: { ...workspace("setup"), setupStatus: "failed" }, + }); + expect(useSessionStore.getState().sessions[serverId].workspaces.get("setup")?.setupStatus).toBe( + "failed", + ); + expect(store.claimFailedSetupSurface({ ...identity, status: "failed" })).toBe(true); + expect(store.claimFailedSetupSurface({ ...identity, status: "failed" })).toBe(false); + expect(useWorkspaceSetupStore.getState().snapshots).toEqual({}); +}); diff --git a/packages/app/src/runtime/directory-sync/workspace-replica.ts b/packages/app/src/runtime/directory-sync/workspace-replica.ts index d229c196a2..2eb107ac4f 100644 --- a/packages/app/src/runtime/directory-sync/workspace-replica.ts +++ b/packages/app/src/runtime/directory-sync/workspace-replica.ts @@ -102,6 +102,7 @@ export class WorkspaceDirectoryReplica { workspaces.set(workspaceId, workspace); } } + for (const workspace of workspaces.values()) this.applySetupStatus(workspace); this.workspaces = workspaces; this.projects = new Map(snapshot.projects); this.rebuildProjectIndex(); @@ -198,7 +199,16 @@ export class WorkspaceDirectoryReplica { return [{ kind: "workspace", type: "upsert", id: workspace.id, value: workspace }]; } + private applySetupStatus(workspace: WorkspaceDescriptor): void { + useWorkspaceSetupStore.getState().applySetupStatus({ + serverId: this.serverId, + workspaceId: workspace.id, + status: workspace.setupStatus ?? null, + }); + } + private setWorkspace(workspace: WorkspaceDescriptor): void { + this.applySetupStatus(workspace); const previous = this.workspaces.get(workspace.id); if (previous?.projectId !== workspace.projectId) { this.workspaceIdsByProject.get(previous?.projectId ?? "")?.delete(workspace.id); diff --git a/packages/app/src/screens/projects-screen.test.tsx b/packages/app/src/screens/projects-screen.test.tsx index 0e3337e240..a91043a709 100644 --- a/packages/app/src/screens/projects-screen.test.tsx +++ b/packages/app/src/screens/projects-screen.test.tsx @@ -182,6 +182,7 @@ function workspaceSummary(overrides: Partial = {}): WorkspaceS status: "done", currentBranch: "main", changeRequestNumber: null, + statusEnteredAt: null, ...overrides, }; } diff --git a/packages/app/src/screens/settings/keyboard-shortcuts-section.tsx b/packages/app/src/screens/settings/keyboard-shortcuts-section.tsx index 8a8c4b42b9..6a8459fc3f 100644 --- a/packages/app/src/screens/settings/keyboard-shortcuts-section.tsx +++ b/packages/app/src/screens/settings/keyboard-shortcuts-section.tsx @@ -20,6 +20,7 @@ import { buildKeyboardShortcutHelpSections, getBindingIdForAction, normalizeCapturedShortcutCombo, + isShortcutCaptureComplete, getDefaultKeysForAction, resolveShortcutKeysForAction, type KeyboardShortcutHelpRow, @@ -269,6 +270,8 @@ function ShortcutRow({ const isBindable = bindingId !== null; const showDone = isCapturing && capturedCombos.length > 0; + const captureComplete = + bindingId !== null && isShortcutCaptureComplete(bindingId, capturedCombos); const showClear = displayChord !== null; // Reset restores the default, so it is only meaningful when there is a // default to restore. A binding that ships without one would otherwise show a @@ -288,11 +291,14 @@ function ShortcutRow({ capturedCombos={capturedCombos} heldModifiers={heldModifiers} /> + {showDone && !captureComplete && ( + {t("settings.shortcuts.captureIndexPrompt")} + )} {isCapturing ? ( <> {showDone && ( - )} @@ -357,7 +363,10 @@ export function KeyboardShortcutsSection() { ); const saveCapture = useCallback(() => { - if (capturingBindingId === null || capturedCombos.length === 0) { + if ( + capturingBindingId === null || + !isShortcutCaptureComplete(capturingBindingId, capturedCombos) + ) { return; } void setOverride(capturingBindingId, capturedCombos.join(" ")); diff --git a/packages/app/src/screens/settings/sidebar/sidebar-nav-section.tsx b/packages/app/src/screens/settings/sidebar/sidebar-nav-section.tsx index 7952a2b1ee..21633e7a10 100644 --- a/packages/app/src/screens/settings/sidebar/sidebar-nav-section.tsx +++ b/packages/app/src/screens/settings/sidebar/sidebar-nav-section.tsx @@ -1,4 +1,4 @@ -import { useCallback, useMemo, type ReactElement } from "react"; +import { useCallback, useMemo, type ComponentType, type ReactElement } from "react"; import { Text, View } from "react-native"; import { useTranslation } from "react-i18next"; import type { TFunction } from "i18next"; @@ -26,7 +26,7 @@ import { type SidebarNavItem, type SidebarSection, } from "@/sidebar-nav/model"; -import { resolvePluginIcon } from "@/plugins/icons"; +import { pluginIconComponent } from "@/plugins/icons"; import { useSidebarNavItems } from "@/sidebar-nav/use-sidebar-nav-items"; import { settingsStyles } from "@/styles/settings"; import { ICON_SIZE, type Theme } from "@/styles/theme"; @@ -50,15 +50,17 @@ const BUILTIN_ICONS: Record = { /** Plugin items register no icon, so they share this one; a legacy `addSidebarItem` keeps its own. */ const PLUGIN_ICON = Blocks; -function NavIcon({ Icon, color = "" }: { Icon: LucideIcon; color?: string }) { +type NavIconComponent = ComponentType<{ size: number; color: string }>; + +function NavIcon({ Icon, color = "" }: { Icon: NavIconComponent; color?: string }) { return ; } const ThemedNavIcon = withUnistyles(NavIcon); -function navItemIcon(item: SidebarNavItem): LucideIcon { +function navItemIcon(item: SidebarNavItem): NavIconComponent { if (item.kind === "builtin") return BUILTIN_ICONS[item.id]; - return item.group.kind === "legacy" ? resolvePluginIcon(item.group.icon) : PLUGIN_ICON; + return item.group.kind === "legacy" ? pluginIconComponent(item.group.icon) : PLUGIN_ICON; } function navItemLabel(t: TFunction, item: SidebarNavItem): string { diff --git a/packages/app/src/screens/workspace/workspace-screen.tsx b/packages/app/src/screens/workspace/workspace-screen.tsx index 48e123c26a..edd28a3af9 100644 --- a/packages/app/src/screens/workspace/workspace-screen.tsx +++ b/packages/app/src/screens/workspace/workspace-screen.tsx @@ -1,3 +1,4 @@ +import { useHostFeature } from "@/runtime/host-features"; import { AssistantFileLinkResolverProvider, createInlinePathOpener, @@ -162,7 +163,7 @@ import { useWorkspaceRecovery } from "@/workspace-recovery/use-workspace-recover import type { WorkspaceRecoveryModel } from "@/workspace-recovery/model"; import { buildWorkspaceTabSnapshot, - deriveWorkspaceAgentVisibility, + createWorkspaceAgentVisibilitySelector, workspaceAgentVisibilityEqual, } from "@/workspace-tabs/agent-visibility"; import { deriveWorkspacePaneState } from "@/screens/workspace/workspace-pane-state"; @@ -223,6 +224,10 @@ const EMPTY_WORKSPACE_SCRIPTS: WorkspaceDescriptor["scripts"] = []; const EMPTY_PINNED_AGENT_IDS = new Set(); const EMPTY_SET = new Set(); +function getWorkspaceSetupStatus(workspace: WorkspaceDescriptor | null | undefined) { + return workspace?.setupStatus ?? null; +} + function getWorkspaceScripts( workspaceDescriptor: WorkspaceDescriptor | null | undefined, ): WorkspaceDescriptor["scripts"] { @@ -1148,14 +1153,17 @@ function WorkspaceScreenContent({ ), }); - const workspaceAgentVisibility = useStoreWithEqualityFn( - useSessionStore, - (state) => - deriveWorkspaceAgentVisibility({ - sessionAgents: state.sessions[normalizedServerId]?.agents, - agentDetails: state.sessions[normalizedServerId]?.agentDetails, + const selectWorkspaceAgentVisibility = useMemo( + () => + createWorkspaceAgentVisibilitySelector({ + serverId: normalizedServerId, workspaceId: normalizedWorkspaceId, }), + [normalizedServerId, normalizedWorkspaceId], + ); + const workspaceAgentVisibility = useStoreWithEqualityFn( + useSessionStore, + selectWorkspaceAgentVisibility, workspaceAgentVisibilityEqual, ); @@ -1310,12 +1318,13 @@ function WorkspaceScreenContent({ }); const lastMainPaneId = lastMainPaneRef.current.paneId; const hasHydratedWorkspaceLayoutStore = useWorkspaceLayoutStoreHydrated(); - const workspaceSetupSnapshot = useWorkspaceSetupStore((state) => - persistenceKey ? (state.snapshots[persistenceKey] ?? null) : null, - ); - const ensureWorkspaceSetupStatus = useWorkspaceSetupStore((state) => state.ensureSetupStatus); + const workspaceSetupStatus = getWorkspaceSetupStatus(workspaceDescriptor); const claimFailedSetupSurface = useWorkspaceSetupStore((state) => state.claimFailedSetupSurface); - const showWorkspaceSetup = shouldShowWorkspaceSetup(workspaceSetupSnapshot); + const supportsSetupObservation = useHostFeature(normalizedServerId, "workspaceSetupObservation"); + const showWorkspaceSetup = shouldShowWorkspaceSetup( + workspaceSetupStatus, + supportsSetupObservation, + ); const uiTabs = useMemo( () => (workspaceLayout ? collectAllTabs(workspaceLayout.root) : EMPTY_UI_TABS), [workspaceLayout], @@ -1621,7 +1630,7 @@ function WorkspaceScreenContent({ if (!persistenceKey) { return; } - if (!shouldSeedWorkspaceSetupTab(workspaceSetupSnapshot)) { + if (!shouldSeedWorkspaceSetupTab(workspaceSetupStatus)) { return; } @@ -1636,6 +1645,7 @@ function WorkspaceScreenContent({ !claimFailedSetupSurface({ serverId: normalizedServerId, workspaceId: normalizedWorkspaceId, + status: workspaceSetupStatus, }) ) { return; @@ -1656,24 +1666,7 @@ function WorkspaceScreenContent({ normalizedServerId, openWorkspaceTabInBackground, persistenceKey, - workspaceSetupSnapshot, - ]); - - useEffect(() => { - if (!isRouteFocused || !client || !normalizedServerId || !normalizedWorkspaceId) { - return; - } - ensureWorkspaceSetupStatus({ - serverId: normalizedServerId, - workspaceId: normalizedWorkspaceId, - client, - }); - }, [ - client, - ensureWorkspaceSetupStatus, - isRouteFocused, - normalizedServerId, - normalizedWorkspaceId, + workspaceSetupStatus, ]); const handleOpenFileFromChat = useCallback( diff --git a/packages/app/src/storage/validated-persist-storage.test.ts b/packages/app/src/storage/validated-persist-storage.test.ts index 7255086e37..4f102761e9 100644 --- a/packages/app/src/storage/validated-persist-storage.test.ts +++ b/packages/app/src/storage/validated-persist-storage.test.ts @@ -63,3 +63,66 @@ describe("createValidatedPersistStorage", () => { expect(backing.values.has("settings")).toBe(false); }); }); + +it("skips repeated immutable states only when requested", async () => { + let writes = 0; + const backing: StateStorage = { + getItem: () => null, + setItem: () => { + writes += 1; + }, + removeItem: () => {}, + }; + const value = { state: { enabled: true }, version: 1 }; + const regular = createValidatedPersistStorage(backing, StateSchema); + await regular.setItem("regular", value); + await regular.setItem("regular", value); + expect(writes).toBe(2); + + const deduplicated = createValidatedPersistStorage(backing, StateSchema, { skipUnchanged: true }); + await deduplicated.setItem("first", value); + await deduplicated.setItem("first", { ...value }); + expect(writes).toBe(3); + await deduplicated.setItem("second", value); + expect(writes).toBe(4); + await deduplicated.setItem("first", { ...value, version: 2 }); + expect(writes).toBe(5); +}); + +it("retries an unchanged state after a failed save", async () => { + let attempts = 0; + const backing = new MemoryStorage(); + const storage = createValidatedPersistStorage( + { + getItem: (name) => backing.getItem(name), + setItem: (name, value) => { + attempts += 1; + if (attempts === 1) return Promise.reject(new Error("storage unavailable")); + backing.setItem(name, value); + }, + removeItem: (name) => backing.removeItem(name), + }, + StateSchema, + { skipUnchanged: true }, + ); + const value = { state: { enabled: true }, version: 1 }; + await expect(storage.setItem("layout", value)).rejects.toThrow("storage unavailable"); + await storage.setItem("layout", value); + expect(attempts).toBe(2); + expect(backing.getItem("layout")).toBe(JSON.stringify(value)); +}); + +it("saves the same state again after removal or rehydration clears invalid storage", async () => { + const backing = new MemoryStorage(); + const storage = createValidatedPersistStorage(backing, StateSchema, { skipUnchanged: true }); + const value = { state: { enabled: true }, version: 1 }; + await storage.setItem("layout", value); + await storage.removeItem("layout"); + await storage.setItem("layout", value); + expect(backing.getItem("layout")).toBe(JSON.stringify(value)); + + backing.values.set("layout", "{"); + await expect(storage.getItem("layout")).resolves.toBeNull(); + await storage.setItem("layout", value); + expect(backing.getItem("layout")).toBe(JSON.stringify(value)); +}); diff --git a/packages/app/src/storage/validated-persist-storage.ts b/packages/app/src/storage/validated-persist-storage.ts index 07459f8642..e9a438daf9 100644 --- a/packages/app/src/storage/validated-persist-storage.ts +++ b/packages/app/src/storage/validated-persist-storage.ts @@ -1,17 +1,22 @@ import { z } from "zod"; -import type { PersistStorage, StateStorage } from "zustand/middleware"; +import type { PersistStorage, StateStorage, StorageValue } from "zustand/middleware"; export function createValidatedPersistStorage( backingStorage: StateStorage, stateSchema: z.ZodType, + // Opt in only when callers preserve state references until values change. + options: { skipUnchanged?: boolean } = {}, ): PersistStorage { const envelopeSchema = z.strictObject({ state: stateSchema, version: z.number().int().nonnegative().optional(), }); + const accepted = new Map>(); + return { getItem: async (name) => { + accepted.delete(name); const raw = await backingStorage.getItem(name); if (raw === null) return null; @@ -31,13 +36,31 @@ export function createValidatedPersistStorage( return result.data; }, setItem: async (name, value) => { + const previous = accepted.get(name); + if ( + options.skipUnchanged && + previous && + previous.state === value.state && + previous.version === value.version + ) + return; const result = envelopeSchema.safeParse(value); if (!result.success) { + accepted.delete(name); await backingStorage.removeItem(name); return; } - await backingStorage.setItem(name, JSON.stringify(result.data)); + if (options.skipUnchanged) accepted.set(name, value); + try { + await backingStorage.setItem(name, JSON.stringify(result.data)); + } catch (error) { + if (accepted.get(name) === value) accepted.delete(name); + throw error; + } + }, + removeItem: (name) => { + accepted.delete(name); + return backingStorage.removeItem(name); }, - removeItem: (name) => backingStorage.removeItem(name), }; } diff --git a/packages/app/src/stores/session-store.ts b/packages/app/src/stores/session-store.ts index 9b70d90486..f7c54e07b2 100644 --- a/packages/app/src/stores/session-store.ts +++ b/packages/app/src/stores/session-store.ts @@ -111,6 +111,7 @@ export interface WorkspaceDescriptor { projectRootPath: string; workspaceDirectory: string; worktreeSlug?: WorkspaceDescriptorPayload["worktreeSlug"]; + setupStatus?: WorkspaceDescriptorPayload["setupStatus"]; projectKind: WorkspaceDescriptorPayload["projectKind"]; workspaceKind: WorkspaceDescriptorPayload["workspaceKind"]; background?: boolean; @@ -149,6 +150,8 @@ export function normalizeWorkspaceDescriptor( // usable directory" (older daemons may omit it; the wire field is optional). workspaceDirectory: normalizeWorkspacePath(payload.workspaceDirectory) ?? "", worktreeSlug: payload.worktreeSlug, + // COMPAT(workspaceSetupObservation): added in v0.12.0, old hosts omit metadata; remove after 2027-04-19. + setupStatus: payload.setupStatus ?? null, projectKind: payload.projectKind, workspaceKind: payload.workspaceKind, background: payload.background ?? false, diff --git a/packages/app/src/stores/workspace-layout-persistence.test.ts b/packages/app/src/stores/workspace-layout-persistence.test.ts new file mode 100644 index 0000000000..d386a40298 --- /dev/null +++ b/packages/app/src/stores/workspace-layout-persistence.test.ts @@ -0,0 +1,54 @@ +import { indexedDB, IDBKeyRange } from "fake-indexeddb"; +import { expect, it } from "vitest"; +import type { StateStorage } from "zustand/middleware"; +import { createWorkspaceLayoutStore } from "./workspace-layout-store"; + +Object.assign(globalThis, { indexedDB, IDBKeyRange }); + +it("skips unchanged reconciliations and immediately saves real layout changes", async () => { + const values = new Map(); + let writes = 0; + const storage: StateStorage = { + getItem: (name) => values.get(name) ?? null, + setItem: (name, value) => { + writes += 1; + values.set(name, value); + }, + removeItem: (name) => { + values.delete(name); + }, + }; + const store = createWorkspaceLayoutStore(undefined, storage); + await store.persist.rehydrate(); + const workspaceKey = "server:workspace"; + const openAgent = (agentId: string) => + store.getState().openTab({ + workspaceKey, + target: { kind: "agent", agentId }, + intent: "reveal", + }); + openAgent("agent-1"); + const layout = store.getState().layoutByWorkspace[workspaceKey]; + const writesBefore = writes; + expect(writesBefore).toBe(1); + for (let index = 0; index < 50; index += 1) { + store.getState().reconcileTabs(workspaceKey, { + agentsHydrated: true, + terminalsHydrated: true, + activeAgentIds: ["agent-1"], + autoOpenAgentIds: ["agent-1"], + knownTerminalIds: [], + standaloneTerminalIds: [], + }); + } + expect(store.getState().layoutByWorkspace[workspaceKey]).toBe(layout); + expect(writes).toBe(writesBefore); + + openAgent("agent-2"); + expect(writes).toBe(writesBefore + 1); + const restored = createWorkspaceLayoutStore(undefined, storage); + await restored.persist.rehydrate(); + expect(restored.getState().layoutByWorkspace[workspaceKey]).toEqual( + store.getState().layoutByWorkspace[workspaceKey], + ); +}); diff --git a/packages/app/src/stores/workspace-layout-store.ts b/packages/app/src/stores/workspace-layout-store.ts index 2aea369df6..4bf86ae093 100644 --- a/packages/app/src/stores/workspace-layout-store.ts +++ b/packages/app/src/stores/workspace-layout-store.ts @@ -1,7 +1,7 @@ import AsyncStorage from "@react-native-async-storage/async-storage"; import { useEffect, useState } from "react"; import { create } from "zustand"; -import { persist } from "zustand/middleware"; +import { persist, type StateStorage } from "zustand/middleware"; import type { z } from "zod"; import { WorkspaceLayoutPersistedStateSchema } from "./workspace-layout-storage"; import type { JsonValue } from "@getpaseo/protocol/agent-types"; @@ -224,6 +224,7 @@ const MAX_TREE_DEPTH = 5; const LEGACY_EXPLORER_SIDEBAR_REFERENCE_WIDTH = 1440; const WORKSPACE_LAYOUT_PERSIST_VERSION = 2; +type WorkspaceLayoutPersistedState = z.infer; function convertLegacyExplorerSidebarRatios( ratiosByWorkspace: Record, @@ -939,8 +940,57 @@ function createExplorerSidebarPane( return targetPaneId ? splitPaneEmpty(workspaceKey, { targetPaneId, position: "right" }) : null; } +const PERSISTED_SLICES = [ + "layoutByWorkspace", + "pinnedAgentIdsByWorkspace", + "splitSizesByWorkspace", + "explorerSidebarWidthByWorkspace", + "explorerSidebarPaneIdByWorkspace", + "sidePaneIdByWorkspace", + "pullRequestTabAutoOpenedByWorkspace", +] as const; + +// Zustand persist re-runs partialize after every set, including ones that return the state +// untouched. Reusing the previous projection while every persisted slice is the same +// reference lets validated storage skip unchanged writes before validation and serialization. +function createPersistedStateProjection() { + let previous: { source: WorkspaceLayoutStore; state: WorkspaceLayoutPersistedState } | null = + null; + return (source: WorkspaceLayoutStore): WorkspaceLayoutPersistedState => { + const last = previous; + if (last && PERSISTED_SLICES.every((slice) => last.source[slice] === source[slice])) { + return last.state; + } + const layoutByWorkspace: Record = {}; + for (const key in source.layoutByWorkspace) { + // Strip ephemeral (commit diff) tabs before persisting so they are + // dropped on reload rather than restored pointing at a rebased SHA. + layoutByWorkspace[key] = stripEphemeralTabsFromLayout( + normalizeLayout(source.layoutByWorkspace[key]), + ); + } + const state: WorkspaceLayoutPersistedState = { + layoutByWorkspace, + pinnedAgentIdsByWorkspace: Object.fromEntries( + Object.entries(source.pinnedAgentIdsByWorkspace).map(([key, agentIds]) => [ + key, + Array.from(agentIds), + ]), + ), + splitSizesByWorkspace: source.splitSizesByWorkspace, + explorerSidebarWidthByWorkspace: source.explorerSidebarWidthByWorkspace, + explorerPaneIdByWorkspace: source.explorerSidebarPaneIdByWorkspace, + sidePaneIdByWorkspace: source.sidePaneIdByWorkspace, + pullRequestTabAutoOpenedByWorkspace: source.pullRequestTabAutoOpenedByWorkspace, + }; + previous = { source, state }; + return state; + }; +} + export function createWorkspaceLayoutStore( ids: WorkspaceLayoutIdSource = defaultWorkspaceLayoutIds, + storage: StateStorage = AsyncStorage, ) { return create()( persist( @@ -2117,33 +2167,12 @@ export function createWorkspaceLayoutStore( { name: "workspace-layout-state", version: WORKSPACE_LAYOUT_PERSIST_VERSION, - storage: createValidatedPersistStorage(AsyncStorage, WorkspaceLayoutPersistedStateSchema), + storage: createValidatedPersistStorage(storage, WorkspaceLayoutPersistedStateSchema, { + skipUnchanged: true, + }), migrate: (persistedState, version) => migrateWorkspaceLayoutPersistedState(persistedState, version, ids), - partialize: (state) => { - const layoutByWorkspace: Record = {}; - for (const key in state.layoutByWorkspace) { - // Strip ephemeral (commit diff) tabs before persisting so they are - // dropped on reload rather than restored pointing at a rebased SHA. - layoutByWorkspace[key] = stripEphemeralTabsFromLayout( - normalizeLayout(state.layoutByWorkspace[key]), - ); - } - return { - layoutByWorkspace, - pinnedAgentIdsByWorkspace: Object.fromEntries( - Object.entries(state.pinnedAgentIdsByWorkspace).map(([key, agentIds]) => [ - key, - Array.from(agentIds), - ]), - ), - splitSizesByWorkspace: state.splitSizesByWorkspace, - explorerSidebarWidthByWorkspace: state.explorerSidebarWidthByWorkspace, - explorerPaneIdByWorkspace: state.explorerSidebarPaneIdByWorkspace, - sidePaneIdByWorkspace: state.sidePaneIdByWorkspace, - pullRequestTabAutoOpenedByWorkspace: state.pullRequestTabAutoOpenedByWorkspace, - }; - }, + partialize: createPersistedStateProjection(), merge: (persistedState, currentState) => { const result = WorkspaceLayoutPersistedStateSchema.safeParse(persistedState); if (!result.success) { diff --git a/packages/app/src/stores/workspace-setup-store.test.ts b/packages/app/src/stores/workspace-setup-store.test.ts index 85c2696f57..17e012c153 100644 --- a/packages/app/src/stores/workspace-setup-store.test.ts +++ b/packages/app/src/stores/workspace-setup-store.test.ts @@ -3,129 +3,13 @@ import { shouldSeedWorkspaceSetupTab, shouldShowWorkspaceSetup, useWorkspaceSetupStore, - type WorkspaceSetupSnapshot, - type WorkspaceSetupStatusClient, - type WorkspaceSetupStatusResult, } from "./workspace-setup-store"; -function makeSnapshot( - status: WorkspaceSetupSnapshot["status"], - error: string | null = null, -): WorkspaceSetupSnapshot { - return { - workspaceId: "workspace-1", - status, - detail: { - type: "worktree_setup", - worktreePath: "/Users/test/project", - branchName: "main", - log: "", - commands: [], - }, - error, - updatedAt: Date.now(), - }; -} - -const DEFAULT_SNAPSHOT: WorkspaceSetupStatusResult["snapshot"] = { - status: "running", - detail: { - type: "worktree_setup", - worktreePath: "/Users/test/project", - branchName: "main", - log: "", - commands: [], - }, - error: null, -}; - -function setupResult( - workspaceId: string, - snapshot: WorkspaceSetupStatusResult["snapshot"] = DEFAULT_SNAPSHOT, -): WorkspaceSetupStatusResult { - return { requestId: "req-1", workspaceId, snapshot }; -} - -function makeClient(handler: (workspaceId: string) => Promise) { - const calls: string[] = []; - const client: WorkspaceSetupStatusClient = { - fetchWorkspaceSetupStatus: (workspaceId) => { - calls.push(workspaceId); - return handler(workspaceId); - }, - }; - return { client, calls }; -} - -function createDeferred() { - let resolve!: (value: T) => void; - let reject!: (reason: unknown) => void; - const promise = new Promise((res, rej) => { - resolve = res; - reject = rej; - }); - return { promise, resolve, reject }; -} - -function flush() { - return new Promise((resolve) => setTimeout(resolve, 0)); -} - -function storedSnapshots() { - return Object.values(useWorkspaceSetupStore.getState().snapshots); -} - -function resolveDefault(workspaceId: string): Promise { - return Promise.resolve(setupResult(workspaceId)); -} - -function rejectThenResolve() { - let attempt = 0; - return (workspaceId: string): Promise => { - attempt += 1; - if (attempt === 1) { - return Promise.reject(new Error("boom")); - } - return resolveDefault(workspaceId); - }; -} - -function nullThenResolve() { - let attempt = 0; - return (workspaceId: string): Promise => { - attempt += 1; - if (attempt === 1) { - return Promise.resolve(setupResult(workspaceId, null)); - } - return resolveDefault(workspaceId); - }; -} - -function mismatchThenResolve() { - let attempt = 0; - return (workspaceId: string): Promise => { - attempt += 1; - if (attempt === 1) { - return Promise.resolve(setupResult("999")); - } - return resolveDefault(workspaceId); - }; -} - -function ensureSetupStatus(client: WorkspaceSetupStatusClient) { - useWorkspaceSetupStore.getState().ensureSetupStatus({ - serverId: "server-1", - workspaceId: "42", - client, - }); -} - describe("workspace-setup-store", () => { beforeEach(() => { useWorkspaceSetupStore.setState({ pendingWorkspaceSetup: null, snapshots: {}, - requestedKeys: new Set(), surfacedFailedSetupKeys: new Set(), }); }); @@ -162,213 +46,39 @@ describe("workspace-setup-store", () => { expect(useWorkspaceSetupStore.getState().pendingWorkspaceSetup).toBeNull(); }); - it("hides empty successful setup snapshots", () => { - expect( - shouldShowWorkspaceSetup({ - workspaceId: "workspace-1", - status: "completed", - detail: { - type: "worktree_setup", - worktreePath: "/Users/test/project", - branchName: "main", - log: "", - commands: [], - }, - error: null, - updatedAt: Date.now(), - }), - ).toBe(false); - }); - - it("shows setup snapshots with commands or errors", () => { - expect( - shouldShowWorkspaceSetup({ - workspaceId: "workspace-1", - status: "completed", - detail: { - type: "worktree_setup", - worktreePath: "/Users/test/project", - branchName: "main", - log: "done\n", - commands: [ - { - index: 1, - command: "npm install", - cwd: "/Users/test/project", - log: "done\n", - status: "completed", - exitCode: 0, - }, - ], - }, - error: null, - updatedAt: Date.now(), - }), - ).toBe(true); - - expect( - shouldShowWorkspaceSetup({ - workspaceId: "workspace-1", - status: "failed", - detail: { - type: "worktree_setup", - worktreePath: "/Users/test/project", - branchName: "main", - log: "", - commands: [], - }, - error: "Failed to parse paseo.json", - updatedAt: Date.now(), - }), - ).toBe(true); - }); - - it("seeds a setup tab for failed or blocked setup", () => { - expect(shouldSeedWorkspaceSetupTab(null)).toBe(false); - expect(shouldSeedWorkspaceSetupTab(makeSnapshot("running"))).toBe(false); - expect(shouldSeedWorkspaceSetupTab(makeSnapshot("completed"))).toBe(false); - expect(shouldSeedWorkspaceSetupTab(makeSnapshot("failed", "Setup failed"))).toBe(true); - expect(shouldSeedWorkspaceSetupTab(makeSnapshot("blocked"))).toBe(true); - }); - - it("claims one failed setup surface until a later setup lifecycle begins", () => { - const store = useWorkspaceSetupStore.getState(); - const identity = { serverId: "server-1", workspaceId: "42" }; - - store.upsertProgress({ - serverId: identity.serverId, - payload: { ...makeSnapshot("failed", "Setup failed"), workspaceId: identity.workspaceId }, - }); - - expect(store.claimFailedSetupSurface(identity)).toBe(true); + it("uses directory metadata to surface failures without requesting setup details", () => { + for (const status of [null, "running", "completed", "failed", "blocked"] as const) { + expect(shouldShowWorkspaceSetup(status)).toBe(status !== null); + expect(shouldSeedWorkspaceSetupTab(status)).toBe(status === "failed" || status === "blocked"); + } + expect(shouldShowWorkspaceSetup(null, false)).toBe(true); + const identity = { serverId: "server-1", workspaceId: "42", status: "failed" as const }; + expect(useWorkspaceSetupStore.getState().snapshots).toEqual({}); + expect(useWorkspaceSetupStore.getState().claimFailedSetupSurface(identity)).toBe(true); expect(useWorkspaceSetupStore.getState().claimFailedSetupSurface(identity)).toBe(false); - - useWorkspaceSetupStore.getState().upsertProgress({ - serverId: identity.serverId, - payload: { ...makeSnapshot("running"), workspaceId: identity.workspaceId }, - }); - useWorkspaceSetupStore.getState().upsertProgress({ - serverId: identity.serverId, - payload: { - ...makeSnapshot("failed", "Setup failed again"), - workspaceId: identity.workspaceId, + useWorkspaceSetupStore.getState().applySetupStatus({ ...identity, status: "running" }); + expect(useWorkspaceSetupStore.getState().claimFailedSetupSurface(identity)).toBe(true); + expect(useWorkspaceSetupStore.getState().snapshots).toEqual({}); + }); + it("replaces cached setup details with an empty reconnect snapshot", () => { + const identity = { serverId: "server", workspaceId: "workspace" }; + const store = useWorkspaceSetupStore.getState(); + store.applySnapshot({ + ...identity, + snapshot: { + status: "failed", + error: "previous setup failed", + detail: { + type: "worktree_setup", + worktreePath: "/workspace", + branchName: "main", + commands: [], + log: "previous output", + }, }, }); - - expect(useWorkspaceSetupStore.getState().claimFailedSetupSurface(identity)).toBe(true); - }); - - it("ensureSetupStatus fetches setup status once and stores the snapshot", async () => { - const { client, calls } = makeClient(resolveDefault); - - ensureSetupStatus(client); - await flush(); - - expect(calls).toEqual(["42"]); - expect(storedSnapshots()).toEqual([ - expect.objectContaining({ workspaceId: "42", status: "running" }), - ]); - }); - - it("ensureSetupStatus does not refetch while a request is in flight", async () => { - const deferred = createDeferred(); - const { client, calls } = makeClient(() => deferred.promise); - - ensureSetupStatus(client); - ensureSetupStatus(client); - - expect(calls).toEqual(["42"]); - - deferred.resolve(setupResult("42")); - await flush(); - - ensureSetupStatus(client); - expect(calls).toEqual(["42"]); - }); - - it("ensureSetupStatus skips fetching when a snapshot already exists", () => { - useWorkspaceSetupStore.getState().upsertProgress({ - serverId: "server-1", - payload: { workspaceId: "42", ...DEFAULT_SNAPSHOT }, - }); - const { client, calls } = makeClient(resolveDefault); - - ensureSetupStatus(client); - - expect(calls).toEqual([]); - }); - - it("ensureSetupStatus ignores a response for a different workspace", async () => { - const { client } = makeClient(() => Promise.resolve(setupResult("999"))); - - ensureSetupStatus(client); - await flush(); - - expect(storedSnapshots()).toHaveLength(0); - }); - - it("ensureSetupStatus does not store a snapshot when the response snapshot is null", async () => { - const { client } = makeClient((workspaceId) => Promise.resolve(setupResult(workspaceId, null))); - - ensureSetupStatus(client); - await flush(); - - expect(storedSnapshots()).toHaveLength(0); - }); - - it("ensureSetupStatus retries after a null-snapshot response", async () => { - const { client, calls } = makeClient(nullThenResolve()); - - ensureSetupStatus(client); - await flush(); - expect(calls).toEqual(["42"]); - expect(storedSnapshots()).toHaveLength(0); - - ensureSetupStatus(client); - await flush(); - expect(calls).toEqual(["42", "42"]); - expect(storedSnapshots()).toHaveLength(1); - }); - - it("ensureSetupStatus retries after a mismatched-workspace response", async () => { - const { client, calls } = makeClient(mismatchThenResolve()); - - ensureSetupStatus(client); - await flush(); - expect(calls).toEqual(["42"]); - expect(storedSnapshots()).toHaveLength(0); - - ensureSetupStatus(client); - await flush(); - expect(calls).toEqual(["42", "42"]); - expect(storedSnapshots()).toHaveLength(1); - }); - - it("ensureSetupStatus clears the in-flight marker on error so a later call retries", async () => { - const { client, calls } = makeClient(rejectThenResolve()); - - ensureSetupStatus(client); - await flush(); - expect(calls).toEqual(["42"]); - expect(storedSnapshots()).toHaveLength(0); - - ensureSetupStatus(client); - await flush(); - expect(calls).toEqual(["42", "42"]); - expect(storedSnapshots()).toHaveLength(1); - }); - - it("ensureSetupStatus retries after the workspace is removed", async () => { - const { client, calls } = makeClient(resolveDefault); - - ensureSetupStatus(client); - await flush(); - expect(calls).toEqual(["42"]); - - useWorkspaceSetupStore.getState().removeWorkspace({ serverId: "server-1", workspaceId: "42" }); - ensureSetupStatus(client); - await flush(); - - expect(calls).toEqual(["42", "42"]); + expect(Object.values(useWorkspaceSetupStore.getState().snapshots)).toHaveLength(1); + store.applySnapshot({ ...identity, snapshot: null }); + expect(useWorkspaceSetupStore.getState().snapshots).toEqual({}); }); }); diff --git a/packages/app/src/stores/workspace-setup-store.ts b/packages/app/src/stores/workspace-setup-store.ts index d0205ba27a..2a40c04c80 100644 --- a/packages/app/src/stores/workspace-setup-store.ts +++ b/packages/app/src/stores/workspace-setup-store.ts @@ -1,6 +1,9 @@ import { createNameId } from "mnemonic-id"; import { generateDraftId } from "@/stores/draft-keys"; -import type { SessionOutboundMessage } from "@getpaseo/protocol/messages"; +import type { + WorkspaceSetupSnapshot as SetupDetailSnapshot, + SessionOutboundMessage, +} from "@getpaseo/protocol/messages"; import { create } from "zustand"; import { buildWorkspaceTabPersistenceKey } from "@/workspace-tabs/model"; @@ -19,30 +22,18 @@ export type WorkspaceSetupProgressPayload = Extract< { type: "workspace_setup_progress" } >["payload"]; -export type WorkspaceSetupStatusResult = Extract< - SessionOutboundMessage, - { type: "workspace_setup_status_response" } ->["payload"]; - -export interface WorkspaceSetupStatusClient { - fetchWorkspaceSetupStatus: (workspaceId: string) => Promise; -} - export interface WorkspaceSetupSnapshot extends WorkspaceSetupProgressPayload { updatedAt: number; } -export function shouldShowWorkspaceSetup(snapshot: WorkspaceSetupSnapshot | null): boolean { - if (!snapshot) { - return false; - } - return ( - snapshot.status === "blocked" || snapshot.error !== null || snapshot.detail.commands.length > 0 - ); +export type WorkspaceSetupStatus = WorkspaceSetupSnapshot["status"] | null; + +export function shouldShowWorkspaceSetup(status: WorkspaceSetupStatus, supported = true): boolean { + return !supported || status !== null; } -export function shouldSeedWorkspaceSetupTab(snapshot: WorkspaceSetupSnapshot | null): boolean { - return snapshot?.status === "failed" || snapshot?.status === "blocked"; +export function shouldSeedWorkspaceSetupTab(status: WorkspaceSetupStatus): boolean { + return status === "failed" || status === "blocked"; } interface WorkspaceSetupStoreState { @@ -50,17 +41,24 @@ interface WorkspaceSetupStoreState { | (PendingWorkspaceSetup & { creationId: string; worktreeSlug: string }) | null; snapshots: Record; - requestedKeys: Set; surfacedFailedSetupKeys: Set; beginWorkspaceSetup: (value: PendingWorkspaceSetup) => void; clearWorkspaceSetup: () => void; - upsertProgress: (input: { serverId: string; payload: WorkspaceSetupProgressPayload }) => void; - claimFailedSetupSurface: (input: { serverId: string; workspaceId: string }) => boolean; - ensureSetupStatus: (input: { + applySnapshot: (input: { serverId: string; workspaceId: string; - client: WorkspaceSetupStatusClient; + snapshot: SetupDetailSnapshot | null; }) => void; + applySetupStatus: (input: { + serverId: string; + workspaceId: string; + status: WorkspaceSetupStatus; + }) => void; + claimFailedSetupSurface: (input: { + serverId: string; + workspaceId: string; + status: WorkspaceSetupStatus; + }) => boolean; removeWorkspace: (input: { serverId: string; workspaceId: string }) => void; clearServer: (serverId: string) => void; } @@ -69,10 +67,9 @@ function buildWorkspaceSetupKey(input: { serverId: string; workspaceId: string } return buildWorkspaceTabPersistenceKey(input); } -export const useWorkspaceSetupStore = create()((set, get) => ({ +export const useWorkspaceSetupStore = create()((set) => ({ pendingWorkspaceSetup: null, snapshots: {}, - requestedKeys: new Set(), surfacedFailedSetupKeys: new Set(), beginWorkspaceSetup: (value) => { set({ @@ -86,30 +83,28 @@ export const useWorkspaceSetupStore = create()((set, g clearWorkspaceSetup: () => { set({ pendingWorkspaceSetup: null }); }, - upsertProgress: ({ serverId, payload }) => { - const key = buildWorkspaceSetupKey({ serverId, workspaceId: payload.workspaceId }); - if (!key) { - return; - } - + applySnapshot: ({ serverId, workspaceId, snapshot }) => { + const key = buildWorkspaceSetupKey({ serverId, workspaceId }); + if (!key) return; set((state) => { - const surfacedFailedSetupKeys = new Set(state.surfacedFailedSetupKeys); - if (payload.status !== "failed" && payload.status !== "blocked") { - surfacedFailedSetupKeys.delete(key); - } - return { - snapshots: { - ...state.snapshots, - [key]: { - ...payload, - updatedAt: Date.now(), - }, - }, - surfacedFailedSetupKeys, - }; + const snapshots = { ...state.snapshots }; + if (snapshot) snapshots[key] = { ...snapshot, workspaceId, updatedAt: Date.now() }; + else delete snapshots[key]; + return { snapshots }; }); }, - claimFailedSetupSurface: ({ serverId, workspaceId }) => { + applySetupStatus: ({ serverId, workspaceId, status }) => { + if (shouldSeedWorkspaceSetupTab(status)) return; + const key = buildWorkspaceSetupKey({ serverId, workspaceId }); + if (!key) return; + set((state) => { + if (!state.surfacedFailedSetupKeys.has(key)) return state; + const surfacedFailedSetupKeys = new Set(state.surfacedFailedSetupKeys); + surfacedFailedSetupKeys.delete(key); + return { surfacedFailedSetupKeys }; + }); + }, + claimFailedSetupSurface: ({ serverId, workspaceId, status }) => { const key = buildWorkspaceSetupKey({ serverId, workspaceId }); if (!key) { return false; @@ -117,10 +112,7 @@ export const useWorkspaceSetupStore = create()((set, g let claimed = false; set((state) => { - if ( - !["failed", "blocked"].includes(state.snapshots[key]?.status ?? "") || - state.surfacedFailedSetupKeys.has(key) - ) { + if (!shouldSeedWorkspaceSetupTab(status) || state.surfacedFailedSetupKeys.has(key)) { return state; } claimed = true; @@ -128,40 +120,6 @@ export const useWorkspaceSetupStore = create()((set, g }); return claimed; }, - ensureSetupStatus: async ({ serverId, workspaceId, client }) => { - const key = buildWorkspaceSetupKey({ serverId, workspaceId }); - if (!key) { - return; - } - const state = get(); - if (state.snapshots[key] || state.requestedKeys.has(key)) { - return; - } - - // requestedKeys is a pure in-flight marker: it dedupes concurrent fetches and is - // released once the request settles. A settle that stored no snapshot (null snapshot, - // mismatched workspace, or error) leaves no marker, so a later call can retry; once a - // snapshot lands, the snapshots[key] guard above prevents redundant refetches. - set((current) => ({ requestedKeys: new Set(current.requestedKeys).add(key) })); - - try { - const response = await client.fetchWorkspaceSetupStatus(workspaceId); - if (response.workspaceId === workspaceId && response.snapshot) { - get().upsertProgress({ - serverId, - payload: { workspaceId: response.workspaceId, ...response.snapshot }, - }); - } - } catch { - // Swallowed: the finally clears the in-flight marker so a later call retries. - } finally { - set((current) => { - const next = new Set(current.requestedKeys); - next.delete(key); - return { requestedKeys: next }; - }); - } - }, removeWorkspace: ({ serverId, workspaceId }) => { const key = buildWorkspaceSetupKey({ serverId, workspaceId }); if (!key) { diff --git a/packages/app/src/styles/density.ts b/packages/app/src/styles/density.ts index 2383685d24..d29547ee88 100644 --- a/packages/app/src/styles/density.ts +++ b/packages/app/src/styles/density.ts @@ -26,15 +26,22 @@ export const density = { tightRowHeight: byLayout(36, 28), /** A square icon-only button that sits in a row or toolbar. */ iconButton: byLayout(44, 28), + /** The space between two blocks of rich text, such as Markdown paragraphs, code and images. */ + blockGap: byLayout(12, 16), }; +/** Resolves a density value for a prop, which Unistyles cannot resolve on its own. */ +export function resolveDensity(rt: { breakpoint?: string }, value: { xs: T; md: T }): T { + return isCompactBreakpoint(rt.breakpoint) ? value.xs : value.md; +} + /** The width or height of a slot that holds an icon of `size`. */ export function densityIconBox(size: DensityIconSize) { return byLayout(COMPACT_ICON_SIZE[size], ICON_SIZE[size]); } export function densityIconSize(rt: { breakpoint?: string }, size: DensityIconSize): number { - return isCompactBreakpoint(rt.breakpoint) ? COMPACT_ICON_SIZE[size] : ICON_SIZE[size]; + return resolveDensity(rt, densityIconBox(size)); } /** Extends a `withUnistyles` icon mapping so the icon also takes its density size. */ diff --git a/packages/app/src/subagents/select.test.ts b/packages/app/src/subagents/select.test.ts index 6835260ca7..38a905183d 100644 --- a/packages/app/src/subagents/select.test.ts +++ b/packages/app/src/subagents/select.test.ts @@ -1,6 +1,11 @@ import type { DaemonClient } from "@getpaseo/client/internal/daemon-client"; import { afterEach, describe, expect, it } from "vitest"; -import { selectProviderSubagentsForParent, selectSubagentsForParent } from "./select"; +import { + createSubagentsForParentSelector, + selectProviderSubagentsForParent, + selectSubagentsForParent, +} from "./select"; +import { createWorkspaceAgentVisibilitySelector } from "@/workspace-tabs/agent-visibility"; import { useProviderSubagentStore } from "./provider-store"; import { useSessionStore, type Agent } from "@/stores/session-store"; @@ -435,3 +440,160 @@ describe("selectSubagentsForParent", () => { ); }); }); + +describe("createSubagentsForParentSelector", () => { + class IterationCountingMap extends Map { + iterations = 0; + override values() { + this.iterations += 1; + return super.values(); + } + override entries() { + this.iterations += 1; + return super.entries(); + } + override [Symbol.iterator]() { + this.iterations += 1; + return super[Symbol.iterator](); + } + } + + const params = { serverId: SERVER_ID, parentAgentId: "parent" }; + + function streamTick(text: string): void { + useSessionStore.getState().setAgentStreamState(SERVER_ID, "parent", { + head: [ + { + kind: "assistant_message", + id: "message-1", + text, + timestamp: new Date("2026-03-08T10:05:00.000Z"), + }, + ], + }); + } + + it("returns the cached rows without walking agents when a stream tick leaves them unchanged", () => { + const agents = new IterationCountingMap( + [ + makeAgent({ id: "parent" }), + makeAgent({ id: "child", parentAgentId: "parent" }), + makeAgent({ id: "unrelated" }), + ].map((agent) => [agent.id, agent]), + ); + useSessionStore.getState().initializeSession(SERVER_ID, null as unknown as DaemonClient); + useSessionStore.getState().setAgents(SERVER_ID, agents); + const select = createSubagentsForParentSelector(params, EMPTY_PENDING_ARCHIVE_IDS); + const before = select(useSessionStore.getState()); + const iterationsAfterFirstSelect = agents.iterations; + + for (let tick = 0; tick < 100; tick += 1) { + streamTick(`token ${tick}`); + expect(select(useSessionStore.getState())).toBe(before); + } + + expect(useSessionStore.getState().sessions[SERVER_ID]?.agents).toBe(agents); + expect(agents.iterations).toBe(iterationsAfterFirstSelect); + expect(before.map((row) => row.id)).toEqual(["child"]); + }); + + it("recomputes when the agents map changes", () => { + setAgents([makeAgent({ id: "parent" }), makeAgent({ id: "child-a", parentAgentId: "parent" })]); + const select = createSubagentsForParentSelector(params, EMPTY_PENDING_ARCHIVE_IDS); + const before = select(useSessionStore.getState()); + + useSessionStore.getState().setAgents(SERVER_ID, (current) => { + const child = makeAgent({ + id: "child-b", + parentAgentId: "parent", + createdAt: new Date("2026-03-08T10:01:00.000Z"), + }); + return new Map(current).set(child.id, child); + }); + const after = select(useSessionStore.getState()); + + expect(after).not.toBe(before); + expect(after.map((row) => row.id)).toEqual(["child-a", "child-b"]); + }); + + it("keeps the previous rows when a changed agents map yields the same rows", () => { + setAgents([ + makeAgent({ id: "parent" }), + makeAgent({ id: "child", parentAgentId: "parent" }), + makeAgent({ id: "unrelated" }), + ]); + const select = createSubagentsForParentSelector(params, EMPTY_PENDING_ARCHIVE_IDS); + const before = select(useSessionStore.getState()); + + useSessionStore.getState().setAgents(SERVER_ID, (current) => { + return new Map(current).set("unrelated", makeAgent({ id: "unrelated", status: "running" })); + }); + + expect(select(useSessionStore.getState())).toBe(before); + }); + + it("applies the pending archive ids it was created with", () => { + setAgents([ + makeAgent({ id: "parent" }), + makeAgent({ id: "child-a", parentAgentId: "parent" }), + makeAgent({ id: "child-b", parentAgentId: "parent" }), + ]); + + const rows = createSubagentsForParentSelector( + params, + new Set(["child-b"]), + )(useSessionStore.getState()); + + expect(rows.map((row) => row.id)).toEqual(["child-a"]); + }); + it("does no agent map walks for 100 stream commits with unchanged source maps", () => { + const agents = new IterationCountingMap( + Array.from({ length: 200 }, (_, i) => { + const agent = makeAgent({ + id: `agent-${i}`, + workspaceId: "workspace", + parentAgentId: i < 3 ? null : `agent-${i % 3}`, + }); + return [agent.id, agent] as const; + }), + ); + useSessionStore.getState().initializeSession(SERVER_ID, null as unknown as DaemonClient); + useSessionStore.getState().setAgents(SERVER_ID, agents); + const selectVisibility = createWorkspaceAgentVisibilitySelector({ + serverId: SERVER_ID, + workspaceId: "workspace", + }); + const selectChildren = Array.from({ length: 3 }, (_, i) => + createSubagentsForParentSelector( + { serverId: SERVER_ID, parentAgentId: `agent-${i}` }, + EMPTY_PENDING_ARCHIVE_IDS, + ), + ); + const select = (state: ReturnType) => { + selectVisibility(state); + selectChildren.forEach((selector) => selector(state)); + }; + select(useSessionStore.getState()); + const before = agents.iterations; + const unsubscribe = useSessionStore.subscribe(select); + try { + for (let tick = 0; tick < 100; tick++) { + useSessionStore.getState().setAgentStreamState(SERVER_ID, "agent-0", { + head: [ + { + kind: "assistant_message", + id: "message", + text: `token ${tick}`, + timestamp: AGENT_TIMESTAMP, + }, + ], + }); + } + expect(useSessionStore.getState().sessions[SERVER_ID]?.agents).toBe(agents); + expect(agents.iterations - before).toBe(0); + } finally { + unsubscribe(); + useSessionStore.getState().clearSession(SERVER_ID); + } + }); +}); diff --git a/packages/app/src/subagents/select.ts b/packages/app/src/subagents/select.ts index 3bb3bddcb6..164a4d1280 100644 --- a/packages/app/src/subagents/select.ts +++ b/packages/app/src/subagents/select.ts @@ -97,6 +97,31 @@ export function selectSubagentsForParent( return rows; } +// Session-store selectors run on every store update, including every stream tick, which +// leaves the agent map untouched. Reuse the previous rows until the map changes, and keep +// them when a recompute yields equal rows so the hook's equality check stays O(1). +export function createSubagentsForParentSelector( + params: SelectSubagentsParams, + pendingArchiveIds: ReadonlySet, +): (state: SessionStoreSnapshot) => SubagentRow[] { + let previousAgents: Map | undefined; + let previousRows: SubagentRow[] | null = null; + + return (state) => { + const agents = state.sessions[params.serverId]?.agents; + if (previousRows && agents === previousAgents) { + return previousRows; + } + + const rows = selectSubagentsForParent(state, params, pendingArchiveIds); + previousAgents = agents; + if (!previousRows || !equal(previousRows, rows)) { + previousRows = rows; + } + return previousRows; + }; +} + export function selectProviderSubagentsForParent( state: ProviderSubagentStoreSnapshot, params: SelectSubagentsParams, @@ -133,12 +158,13 @@ export function selectProviderSubagentsForParent( } export function useSubagentsForParent(params: SelectSubagentsParams): SubagentRow[] { - const pendingArchiveIds = usePendingArchiveAgentIds(params.serverId); - const paseoRows = useStoreWithEqualityFn( - useSessionStore, - (state) => selectSubagentsForParent(state, params, pendingArchiveIds), - equal, + const { serverId, parentAgentId } = params; + const pendingArchiveIds = usePendingArchiveAgentIds(serverId); + const selectPaseoRows = useMemo( + () => createSubagentsForParentSelector({ serverId, parentAgentId }, pendingArchiveIds), + [serverId, parentAgentId, pendingArchiveIds], ); + const paseoRows = useStoreWithEqualityFn(useSessionStore, selectPaseoRows, equal); const supported = useSessionStore( (state) => state.sessions[params.serverId]?.serverInfo?.features?.providerSubagents === true, ); diff --git a/packages/app/src/subagents/track.tsx b/packages/app/src/subagents/track.tsx index c1834587d2..43f659c534 100644 --- a/packages/app/src/subagents/track.tsx +++ b/packages/app/src/subagents/track.tsx @@ -1,11 +1,12 @@ -import { useCallback, type ReactElement } from "react"; -import { Pressable, Text, View } from "react-native"; +import { useCallback, useMemo, type ReactElement, type ReactNode } from "react"; +import { Text, View } from "react-native"; import { useTranslation } from "react-i18next"; import { Archive, Unlink } from "lucide-react-native"; import { StyleSheet, withUnistyles } from "react-native-unistyles"; import { useProviderIcon } from "@/components/provider-icons"; import { ComposerTrackActions, ComposerTrackPill, ComposerTrackRow } from "@/composer/tracks"; -import { Tooltip, TooltipContent, TooltipTrigger } from "@/components/ui/tooltip"; +import { mutedIconColorMapping } from "@/components/ui/icon-button-chrome"; +import { ToolbarButton, paneContentToolbarIconSize } from "@/components/ui/pane-content-toolbar"; import { useIsCompactFormFactor } from "@/constants/layout"; import { isNative } from "@/constants/platform"; import { @@ -13,6 +14,7 @@ import { type WorkspaceTabPresentation, } from "@/screens/workspace/workspace-tab-presentation"; import type { Theme } from "@/styles/theme"; +import { useAgentFactsLine } from "@/panels/agent-facts-line"; import { getPanelManifest } from "@/panels/panel-manifest"; import type { SubagentRow } from "./select"; import type { ArchiveFinishedStatus } from "./use-archive-finished"; @@ -48,7 +50,6 @@ export interface SubagentsTrackProps { const IDLE_ARCHIVE_FINISHED_STATUS: ArchiveFinishedStatus = { kind: "idle" }; -/** Leading and action glyphs share one size so rows keep a single icon column. */ const ROW_ICON_SIZE = 14; function useRowPresentation(row: SubagentRow, serverId: string): WorkspaceTabPresentation { @@ -219,18 +220,21 @@ function SubagentsTrackRow({ ({ active }: { active: boolean }) => ( <> - - {displayLabel} - - {presentation.subtitle ? ( - - {presentation.subtitle} + + + {displayLabel} - ) : null} + {row.kind === "paseo" ? ( + + ) : ( + + )} + {row.kind === "paseo" ? ( ; +} + +function SubagentFacts({ rowId, text }: { rowId: string; text: string | null }) { + if (!text) return null; + return ( + + {text} + + ); +} + function SubagentRowActions({ rowId, displayLabel, + compact, visible, onDetachPress, onArchivePress, }: { rowId: string; displayLabel: string; + compact: boolean; visible: boolean; onDetachPress?: () => void; onArchivePress: () => void; }): ReactElement { const { t } = useTranslation(); + const iconSize = paneContentToolbarIconSize(compact); return ( {onDetachPress ? ( + testID={`subagents-track-detach-${rowId}`} + > + + ) : null} + testID={`subagents-track-archive-${rowId}`} + > + + ); } -type SubagentActionIcon = "archive" | "detach"; - -function renderSubagentActionIcon(icon: SubagentActionIcon, isActive: boolean): ReactElement { - const uniProps = isActive ? foregroundColorMapping : foregroundMutedColorMapping; - if (icon === "detach") { - return ; - } - return ; -} - +/** The standard icon action, with a tooltip that names the action without repeating the row. */ function SubagentActionButton({ - accessibilityLabel, - testID, + label, tooltipLabel, - icon, - visible, + compact, onPress, + testID, + children, }: { - accessibilityLabel: string; - testID: string; + label: string; tooltipLabel: string; - icon: SubagentActionIcon; - visible: boolean; + compact: boolean; onPress: () => void; + testID: string; + children: ReactNode; }): ReactElement { + const tooltip = useMemo( + () => {tooltipLabel}, + [tooltipLabel], + ); return ( - - - - {({ hovered, pressed }) => renderSubagentActionIcon(icon, hovered || pressed)} - - - - {tooltipLabel} - - + + {children} + ); } @@ -360,9 +374,24 @@ const styles = StyleSheet.create((theme) => ({ fontSize: theme.fontSize.base, color: theme.colors.foreground, }, - // Trailing metadata — provider context on a subagent row, progress on the archive row. No width - // cap: the panel's own ceiling bounds it. It shrinks twice as fast as the label, so a wordy - // provider subtitle gives way first instead of squeezing the thing that names the row. + // Title over facts. The facts sit under the title rather than beside it, so a long task name + // keeps the row's full width and neither line truncates the other. + rowText: { + flexGrow: 1, + flexShrink: 1, + flexBasis: "auto", + minWidth: 0, + }, + rowTitle: { + fontSize: theme.fontSize.base, + color: theme.colors.foreground, + }, + rowFacts: { + fontSize: theme.fontSize.sm, + color: theme.colors.foregroundMuted, + }, + // Progress on the archive row. It shrinks twice as fast as the label, so a long retry count + // gives way first instead of squeezing the thing that names the row. rowTrailing: { flexShrink: 2, minWidth: 0, @@ -381,11 +410,6 @@ const styles = StyleSheet.create((theme) => ({ gap: theme.spacing[1], opacity: 0, }, - actionButton: { - padding: theme.spacing[1], - alignItems: "center", - justifyContent: "center", - }, tooltipText: { fontSize: theme.fontSize.sm, color: theme.colors.foreground, diff --git a/packages/app/src/terminal/native-renderer/terminal-selection.test.ts b/packages/app/src/terminal/native-renderer/terminal-selection.test.ts index 5f2a4bb593..c188671ffe 100644 --- a/packages/app/src/terminal/native-renderer/terminal-selection.test.ts +++ b/packages/app/src/terminal/native-renderer/terminal-selection.test.ts @@ -41,6 +41,93 @@ function rowWithText( } describe("native terminal selection", () => { + it.each([ + { startCol: 1, endCol: 8, expected: "한글 문장" }, + { startCol: 3, endCol: 8, expected: "글 문장" }, + { startCol: 1, endCol: 1, expected: "한" }, + { startCol: 0, endCol: 0, expected: "한" }, + { startCol: 0, endCol: 1, expected: "한" }, + { startCol: 4, endCol: 6, expected: " 문" }, + ])( + "copies complete wide characters for selected columns $startCol through $endCol", + async ({ startCol, endCol, expected }) => { + const terminal = createNativeHeadlessTerminal({ rows: 3, cols: 30 }); + const copied: string[] = []; + try { + await terminal.write("한글 문장"); + const bounds = terminal.getBufferBounds(); + const selection = createTerminalSelectionModel(); + selection.begin({ + coordinate: { row: bounds.cursorRow, col: endCol }, + bounds, + }); + selection.update({ + coordinate: { row: bounds.cursorRow, col: startCol }, + bounds, + }); + + await copyTerminalSelection({ + terminal, + selection: selection.getSnapshot().range, + clipboard: { + writeText: async (text) => { + copied.push(text); + }, + }, + }); + + expect(copied).toEqual([expected]); + } finally { + terminal.dispose(); + } + }, + ); + + it("copies Korean output without adding spaces for continuation cells", async () => { + const terminal = createNativeHeadlessTerminal({ rows: 3, cols: 30 }); + const copied: string[] = []; + try { + await terminal.write("한글 문장"); + const bounds = terminal.getBufferBounds(); + await copyTerminalSelection({ + terminal, + selection: { + start: { row: bounds.cursorRow, col: 0 }, + end: { row: bounds.cursorRow, col: bounds.cursorCol - 1 }, + coordinateEpoch: bounds.coordinateEpoch, + }, + clipboard: { + writeText: async (text) => { + copied.push(text); + }, + }, + }); + expect(copied).toEqual(["한글 문장"]); + } finally { + terminal.dispose(); + } + }); + + it("copies Korean text and real spaces without wide-character continuation spaces", async () => { + const terminal = createNativeHeadlessTerminal({ rows: 3, cols: 30 }); + try { + await terminal.write("한글 문장 | 성공"); + const bounds = terminal.getBufferBounds(); + expect( + extractTerminalSelectedText({ + terminal, + selection: { + start: { row: bounds.cursorRow, col: 0 }, + end: { row: bounds.cursorRow, col: bounds.cursorCol - 1 }, + coordinateEpoch: bounds.coordinateEpoch, + }, + }), + ).toBe("한글 문장 | 성공"); + } finally { + terminal.dispose(); + } + }); + it("expands a long-press coordinate to the whole terminal word", async () => { const terminal = createNativeHeadlessTerminal({ rows: 4, cols: 32, scrollbackLines: 20 }); await terminal.write("before PASEO_TARGET after\r\n"); @@ -64,6 +151,61 @@ describe("native terminal selection", () => { }); }); + it.each([ + { col: 0, expected: "한글", startCol: 0, endCol: 3 }, + { col: 1, expected: "한글", startCol: 0, endCol: 3 }, + { col: 2, expected: "한글", startCol: 0, endCol: 3 }, + { col: 3, expected: "한글", startCol: 0, endCol: 3 }, + { col: 5, expected: "문장", startCol: 5, endCol: 8 }, + { col: 6, expected: "문장", startCol: 5, endCol: 8 }, + { col: 7, expected: "문장", startCol: 5, endCol: 8 }, + { col: 8, expected: "문장", startCol: 5, endCol: 8 }, + ])( + "selects the whole Korean word from column $col, including continuation cells", + async ({ col, expected, startCol, endCol }) => { + const terminal = createNativeHeadlessTerminal({ rows: 3, cols: 30 }); + try { + await terminal.write("한글 문장"); + const bounds = terminal.getBufferBounds(); + const row = bounds.cursorRow; + const selection = resolveTerminalWordSelection({ terminal, coordinate: { row, col } }); + + expect({ selection, text: extractTerminalSelectedText({ terminal, selection }) }).toEqual({ + selection: { + start: { row, col: startCol }, + end: { row, col: endCol }, + coordinateEpoch: bounds.coordinateEpoch, + }, + text: expected, + }); + } finally { + terminal.dispose(); + } + }, + ); + + it.each([ + { text: "한글 문장", col: 4, expected: "" }, + { text: "(한글)", col: 2, expected: "한글" }, + { text: "漢字 test", col: 1, expected: "漢字" }, + { text: "a한b x", col: 2, expected: "a한b" }, + { text: "🙂🙂 ok", col: 1, expected: "🙂🙂" }, + { text: "e\u0301한 ok", col: 2, expected: "e\u0301한" }, + { text: "한글", col: 3, expected: "한글" }, + ])("preserves word boundaries in $text at column $col", async ({ text, col, expected }) => { + const terminal = createNativeHeadlessTerminal({ rows: 3, cols: 30 }); + try { + await terminal.write(text); + const selection = resolveTerminalWordSelection({ + terminal, + coordinate: { row: terminal.getBufferBounds().cursorRow, col }, + }); + expect(extractTerminalSelectedText({ terminal, selection })).toBe(expected); + } finally { + terminal.dispose(); + } + }); + it("maps screen coordinates through the current visible window", () => { expect( hitTestTerminalSelectionCell({ diff --git a/packages/app/src/terminal/native-renderer/terminal-selection.ts b/packages/app/src/terminal/native-renderer/terminal-selection.ts index 1bda469e42..450a3813ac 100644 --- a/packages/app/src/terminal/native-renderer/terminal-selection.ts +++ b/packages/app/src/terminal/native-renderer/terminal-selection.ts @@ -1,4 +1,4 @@ -import type { NativeHeadlessTerminal } from "./headless-terminal-state"; +import type { NativeHeadlessTerminal, NativeTerminalCell } from "./headless-terminal-state"; import type { TerminalGridCellMetrics } from "./terminal-grid-metrics"; export interface TerminalBufferCoordinate { @@ -101,6 +101,10 @@ interface TerminalSelectionState { const TERMINAL_WORD_SEPARATORS = " ()[]{}',\"`"; +function isTerminalWordSeparator(cell: NativeTerminalCell): boolean { + return cell.width !== 0 && TERMINAL_WORD_SEPARATORS.includes(cell.char || " "); +} + function compareCoordinates( left: TerminalBufferCoordinate, right: TerminalBufferCoordinate, @@ -183,8 +187,7 @@ export function resolveTerminalWordSelection( if (!cells || input.coordinate.col < 0 || input.coordinate.col >= cells.length) { return null; } - const target = cells[input.coordinate.col]?.char || " "; - if (TERMINAL_WORD_SEPARATORS.includes(target)) { + if (isTerminalWordSeparator(cells[input.coordinate.col])) { return { start: input.coordinate, end: input.coordinate, @@ -195,13 +198,11 @@ export function resolveTerminalWordSelection( let startCol = input.coordinate.col; let endCol = input.coordinate.col; while (startCol > 0) { - const previous = cells[startCol - 1]?.char || " "; - if (TERMINAL_WORD_SEPARATORS.includes(previous)) break; + if (isTerminalWordSeparator(cells[startCol - 1])) break; startCol -= 1; } while (endCol + 1 < cells.length) { - const next = cells[endCol + 1]?.char || " "; - if (TERMINAL_WORD_SEPARATORS.includes(next)) break; + if (isTerminalWordSeparator(cells[endCol + 1])) break; endCol += 1; } @@ -324,10 +325,17 @@ export function extractTerminalSelectedText(input: TerminalSelectedTextInput): s const cells = window.rows[offset] ?? []; const startsOnThisRow = row === selection.start.row; const endsOnThisRow = row === selection.end.row; - const startCol = startsOnThisRow ? selection.start.col : 0; + let startCol = Math.max(0, startsOnThisRow ? selection.start.col : 0); + // Selecting either half highlights the whole wide character, so copy its leading cell too. + if (startCol > 0 && cells[startCol]?.width === 0) { + startCol -= 1; + } const endCol = endsOnThisRow ? selection.end.col : cells.length - 1; - const selectedCells = cells.slice(Math.max(0, startCol), Math.max(0, endCol) + 1); - const line = selectedCells.map((cell) => cell.char || " ").join(""); + const selectedCells = cells.slice(startCol, Math.max(0, endCol) + 1); + const line = selectedCells + .filter((cell) => cell.width !== 0) + .map((cell) => cell.char) + .join(""); if (offset > 0 && window.wrappedRows[offset] !== true) { text += "\n"; } diff --git a/packages/app/src/timeline/replica.test.ts b/packages/app/src/timeline/replica.test.ts index fa7521e487..47bd36596a 100644 --- a/packages/app/src/timeline/replica.test.ts +++ b/packages/app/src/timeline/replica.test.ts @@ -77,6 +77,90 @@ function applySynced(agentId: string, seq: number): void { afterEach(() => useSessionStore.getState().clearSession(SERVER_ID)); describe("viewed timeline persistence", () => { + it("keeps one complete reply when live chunks arrive before a cached chat catches up", async () => { + useSessionStore.getState().initializeSession(SERVER_ID, null); + const partial = "Paragraph 1. Paragraph 2."; + const complete = `${partial} Paragraph 3. END`; + const owner = createOwner({ + readTimeline: async () => ({ + agentId: AGENT_ID, + items: [{ ...item("reply-1", partial, 4), messageId: "reply-1" }], + range: { epoch: "epoch-1", startSeq: 1, endSeq: 4 }, + hasOlder: false, + }), + commitTimeline: () => undefined, + }); + try { + owner.replaceVisibleAgentIds("test", [AGENT_ID]); + await expect + .poll( + () => + selectAgentTimelineState(useSessionStore.getState().sessions[SERVER_ID], AGENT_ID) + .status, + ) + .toBe("painted"); + owner.enqueueStreamEvent(AGENT_ID, { + event: { + type: "timeline", + provider: "codex", + item: { type: "assistant_message", text: " Paragraph 3.", messageId: "reply-1" }, + } as AgentStreamEventPayload, + seq: 5, + epoch: "epoch-1", + timestamp: new Date("2026-08-26T10:00:01.000Z"), + }); + owner.flushStreamAgent(AGENT_ID); + owner.applyTimelineResponse({ + requestId: "resume", + agentId: AGENT_ID, + agent: null, + direction: "after", + projection: "projected", + reset: false, + epoch: "epoch-1", + window: { minSeq: 1, maxSeq: 6, nextSeq: 7 }, + startCursor: { epoch: "epoch-1", seq: 5 }, + endCursor: { epoch: "epoch-1", seq: 6 }, + entries: [ + { + provider: "codex", + item: { type: "assistant_message", text: complete, messageId: "reply-1" }, + timestamp: "2026-08-26T10:00:02.000Z", + seqStart: 2, + seqEnd: 6, + sourceSeqRanges: [{ startSeq: 2, endSeq: 6 }], + collapsed: ["assistant_merge"], + }, + ], + error: null, + hasNewer: false, + hasOlder: false, + staleCursor: false, + gap: false, + }); + const replyTexts = () => { + const session = useSessionStore.getState().sessions[SERVER_ID]; + return [ + ...(session?.agentStreamTail.get(AGENT_ID) ?? []), + ...(session?.agentStreamHead.get(AGENT_ID) ?? []), + ] + .filter((entry) => entry.kind === "assistant_message") + .map((entry) => entry.text); + }; + expect.soft(replyTexts()).toEqual([complete]); + owner.enqueueStreamEvent(AGENT_ID, { + event: { type: "turn_completed", provider: "codex" } as AgentStreamEventPayload, + seq: 7, + epoch: "epoch-1", + timestamp: new Date("2026-08-26T10:00:03.000Z"), + }); + owner.flushStreamAgent(AGENT_ID); + expect.soft(replyTexts()).toEqual([complete]); + } finally { + owner.dispose(); + } + }); + it("shares an in-flight cache preparation with the viewed owner", async () => { useSessionStore.getState().initializeSession(SERVER_ID, null); let release!: (value: CachedTimeline) => void; diff --git a/packages/app/src/timeline/session-stream-reducers.ts b/packages/app/src/timeline/session-stream-reducers.ts index dce9daa4da..34a461d893 100644 --- a/packages/app/src/timeline/session-stream-reducers.ts +++ b/packages/app/src/timeline/session-stream-reducers.ts @@ -811,7 +811,7 @@ function reconcileOverlappingProjectedAssistant(params: { }; const headMatch = findMatch(params.head); - const tailMatch = headMatch ? null : findMatch(params.tail); + const tailMatch = findMatch(params.tail); const match = headMatch ?? tailMatch; if (!match) { return { tail: params.tail, head: params.head, reconciled: false }; @@ -833,8 +833,20 @@ function reconcileOverlappingProjectedAssistant(params: { }; if (headMatch) { + const tailCursor = tailMatch?.current.timelineCursor; + const replacesCachedPrefix = + tailMatch !== null && + tailCursor?.epoch === params.epoch && + unit.sourceSeqRanges.some( + (range) => range.startSeq <= tailCursor.seq && tailCursor.seq <= range.endSeq, + ); return { - tail: params.tail, + // Live chunks can arrive before catch-up while their cached prefix is still painted. + // The projected reply owns both copies; keeping the prefix would duplicate it and + // cause completion to discard the updated head as an already-committed item. + tail: replacesCachedPrefix + ? [...params.tail.slice(0, tailMatch.index), ...params.tail.slice(tailMatch.index + 1)] + : params.tail, head: replaceMatch(params.head, headMatch.index), reconciled: true, }; diff --git a/packages/app/src/tool-calls/presentation.test.ts b/packages/app/src/tool-calls/presentation.test.ts index fde0ba020f..fc609ee8f6 100644 --- a/packages/app/src/tool-calls/presentation.test.ts +++ b/packages/app/src/tool-calls/presentation.test.ts @@ -1,9 +1,11 @@ +import type { AgentMessage } from "@getpaseo/protocol/agent-message"; import type { ToolCallDetail } from "@getpaseo/protocol/agent-types"; import { describe, expect, it } from "vitest"; import { buildToolCallPresentation, type ToolCallPresentationIcon } from "./presentation"; const fakeIcons = { + paseo: (() => null) as ToolCallPresentationIcon, brain: (() => null) as ToolCallPresentationIcon, eye: (() => null) as ToolCallPresentationIcon, wrench: (() => null) as ToolCallPresentationIcon, @@ -12,7 +14,11 @@ const fakeIcons = { function fakeResolveIcon( toolName: string, detail: ToolCallDetail | undefined, + agentMessage: AgentMessage | undefined, ): ToolCallPresentationIcon { + if (agentMessage) { + return fakeIcons.paseo; + } if (detail?.type === "plan") { return fakeIcons.brain; } @@ -94,32 +100,35 @@ describe("tool-call presentation", () => { }); it.each([ - ["message", "Message from QA messenger"], - ["finished", "QA messenger finished"], - ["errored", "QA messenger errored"], - ["permission-required", "QA messenger needs permission"], - ["closed", "QA messenger closed"], -] as const)("presents %s from structured provenance without a second label", (event, heading) => { - const presentation = buildToolCallPresentation({ - toolName: "internal_name_should_not_be_visible", - status: "completed", - error: null, - detail: { type: "plain_text", label: "legacy summary", text: "legacy body" }, - agentMessage: { - event, - sender: { id: "server::sender", title: "QA messenger" }, - text: "The delivered message.", - }, - resolveIcon: fakeResolveIcon, - }); - expect(presentation.displayName).toBe(heading); - expect(presentation.summary).toBeUndefined(); - expect(presentation.detail).toEqual({ - type: "plain_text", - icon: "bot", - text: "From agent: server::sender\n\nThe delivered message.", - }); -}); + ["message", "Message received"], + ["finished", "Agent finished"], + ["errored", "Agent errored"], + ["permission-required", "Agent needs permission"], + ["closed", "Agent closed"], +] as const)( + "presents %s with a fixed label, the sender as context, and the Paseo icon", + (event, heading) => { + const presentation = buildToolCallPresentation({ + toolName: "internal_name_should_not_be_visible", + status: "completed", + error: null, + detail: { type: "plain_text", label: "legacy summary", text: "legacy body", icon: "bot" }, + agentMessage: { + event, + sender: { id: "server::sender", title: "QA messenger" }, + text: "The delivered message.", + }, + resolveIcon: fakeResolveIcon, + }); + expect(presentation.displayName).toBe(heading); + expect(presentation.summary).toBe("QA messenger"); + expect(presentation.icon).toBe(fakeIcons.paseo); + expect(presentation.detail).toEqual({ + type: "plain_text", + text: "From agent: server::sender\n\nThe delivered message.", + }); + }, +); it("uses an opaque sender ID when no title is available", () => { const presentation = buildToolCallPresentation({ @@ -129,5 +138,19 @@ it("uses an opaque sender ID when no title is available", () => { agentMessage: { event: "message", sender: { id: "remote::worker" }, text: "Hello" }, resolveIcon: fakeResolveIcon, }); - expect(presentation.displayName).toBe("Message from remote::worker"); + expect(presentation.displayName).toBe("Message received"); + expect(presentation.summary).toBe("remote::worker"); +}); + +it("shows the target agent title as context for Paseo agent tools", () => { + const presentation = buildToolCallPresentation({ + toolName: "mcp__paseo__kill_agent", + status: "completed", + error: null, + detail: { type: "unknown", input: { agentId: "agt_1" }, output: null }, + targetAgentTitle: "Reviewer", + resolveIcon: fakeResolveIcon, + }); + expect(presentation.displayName).toBe("Kill agent"); + expect(presentation.summary).toBe("Reviewer"); }); diff --git a/packages/app/src/tool-calls/presentation.ts b/packages/app/src/tool-calls/presentation.ts index f25d752624..b0ffbb4d5d 100644 --- a/packages/app/src/tool-calls/presentation.ts +++ b/packages/app/src/tool-calls/presentation.ts @@ -1,5 +1,5 @@ import type { AgentMessage } from "@getpaseo/protocol/agent-message"; -import { buildAgentMessageDisplay } from "@getpaseo/protocol/agent-message-display"; +import { buildAgentMessageDisplay } from "@getpaseo/protocol/paseo-tool-presentation/index"; import type { PlanOutcome } from "@/components/plan-card"; import type { ComponentType } from "react"; import type { ToolCallDetail } from "@getpaseo/protocol/agent-types"; @@ -22,6 +22,7 @@ interface BuildToolCallPresentationInput { detail?: ToolCallDetail; cwd?: string; metadata?: Record; + targetAgentTitle?: string; resolveIcon: ToolCallIconResolver; } @@ -42,6 +43,7 @@ export interface ToolCallPresentation { export type ToolCallIconResolver = ( toolName: string, detail: ToolCallDetail | undefined, + agentMessage: AgentMessage | undefined, ) => ToolCallPresentationIcon; function displayStatus(status: ToolCallStatus): ToolCallDisplayInput["status"] { @@ -67,6 +69,7 @@ export function buildToolCallPresentation( detail: detailForDisplay, metadata: input.metadata, cwd: input.cwd, + targetAgentTitle: input.targetAgentTitle, }); const isLoadingDetails = isPendingToolCallDetail({ detail, @@ -80,7 +83,7 @@ export function buildToolCallPresentation( displayName: displayModel.displayName, summary: displayModel.summary, errorText: displayModel.errorText, - icon: input.resolveIcon(input.toolName, detail), + icon: input.resolveIcon(input.toolName, detail, input.agentMessage), isLoadingDetails, hasDetails, canOpenDetails: hasDetails || isLoadingDetails, diff --git a/packages/app/src/tool-calls/use-target-agent-title.ts b/packages/app/src/tool-calls/use-target-agent-title.ts new file mode 100644 index 0000000000..877478d396 --- /dev/null +++ b/packages/app/src/tool-calls/use-target-agent-title.ts @@ -0,0 +1,19 @@ +import type { ToolCallDetail } from "@getpaseo/protocol/agent-types"; +import { getPaseoToolTargetAgentId } from "@getpaseo/protocol/paseo-tool-presentation/index"; +import { useSessionStore } from "@/stores/session-store"; + +/** Title of the agent a Paseo tool call acts on, when this host knows it. */ +export function useTargetAgentTitle(input: { + serverId: string | undefined; + toolName: string; + detail: ToolCallDetail | undefined; +}): string | undefined { + const agentId = getPaseoToolTargetAgentId(input.toolName, input.detail); + const { serverId } = input; + return useSessionStore((state) => { + if (!serverId || !agentId) return undefined; + const session = state.sessions[serverId]; + const agent = session?.agents.get(agentId) ?? session?.agentDetails.get(agentId); + return agent?.title ?? undefined; + }); +} diff --git a/packages/app/src/usage/balance-bar.tsx b/packages/app/src/usage/balance-bar.tsx index 751193eec0..38b2f0804a 100644 --- a/packages/app/src/usage/balance-bar.tsx +++ b/packages/app/src/usage/balance-bar.tsx @@ -41,11 +41,17 @@ function fillToneStyle(tone: UsageTone) { } } -export function UsageBalanceBar({ balance }: { balance: UsageBalance }) { +export function UsageBalanceBar({ + balance, + retained = false, +}: { + balance: UsageBalance; + retained?: boolean; +}) { const { i18n } = useTranslation(); const { amountText, usedPct } = resolveBalance(balance, i18n.language); const tone = balance.tone ?? "default"; - const resetLabel = formatResetLabel(balance.resetsAt); + const resetLabel = formatResetLabel(balance.resetsAt, retained); const fillStyle = useMemo>( () => [styles.fill, fillToneStyle(tone), { width: `${clampPct(usedPct ?? 0)}%` }], diff --git a/packages/app/src/usage/card.tsx b/packages/app/src/usage/card.tsx index a1936e0f97..562f3805a1 100644 --- a/packages/app/src/usage/card.tsx +++ b/packages/app/src/usage/card.tsx @@ -16,7 +16,7 @@ import { useCompactTimeAgo } from "@/hooks/use-time-ago"; import { UsageBalanceBar } from "./balance-bar"; import { usageCopy } from "./copy"; import type { UsageDisplay } from "./display"; -import { formatUsageFreshness, type UsageRefresh } from "./model"; +import { formatUsageFreshness, resolveUsageReport, type UsageRefresh } from "./model"; import { useReportRefresh } from "./queries"; import { UsageSourceIcon } from "./source-icon"; import type { UsageReport, UsageReportEntry, UsageWindow } from "./types"; @@ -27,31 +27,6 @@ function statusText(report: UsageReport): string | null { return report.status === "error" ? "Error" : "Unavailable"; } -function reportContent(report: UsageReport) { - if (report.status === "available") - return { - windows: report.windows, - balances: report.balances ?? [], - details: report.details ?? [], - message: undefined, - }; - const message = - report.status === "unavailable" ? usageCopy.problem(report.problem) : report.error; - return { windows: [], balances: [], details: [], message }; -} - -function reportMessages(entry: UsageReportEntry): string[] { - if (entry.report.status === "available") return []; - if (entry.loginErrors) - return entry.loginErrors.map( - (login) => `${login.harness}: ${reportContent(login.report).message}`, - ); - // COMPAT(usageLoginErrors): added in v0.11.0, remove after 2027-04-05 once daemon floor >= v0.11.0. - return [ - entry.report.status === "error" ? entry.report.error : usageCopy.problem(entry.report.problem), - ]; -} - const ThemedRotateCw = withUnistyles(RotateCw); const ThemedLoadingSpinner = withUnistyles(LoadingSpinner); @@ -81,8 +56,8 @@ export function UsageCard({ const usage = entry.report; const status = statusText(usage); const footer = entry.account.label ?? null; - const { windows, balances, details } = reportContent(usage); - const messages = reportMessages(entry); + const { windows, balances, details, planLabel, successfulAt, retained, messages } = + resolveUsageReport(entry); const containerStyle = useMemo( () => [styles.container, compact ? styles.containerCompact : styles.containerPadded], @@ -104,9 +79,7 @@ export function UsageCard({ {entry.sourceLabel} - {usage.status === "available" && usage.planLabel ? ( - - ) : null} + {planLabel ? : null} {status ? ( @@ -117,7 +90,8 @@ export function UsageCard({ {refreshable ? ( ))} {balances.map((balance) => ( - + ))} ) : null} @@ -170,7 +145,8 @@ export function UsageCard({ {showsFreshnessInline ? ( @@ -192,7 +168,9 @@ function CardWindowBar({ window, display, pinnable, + retained, }: { + retained: boolean; entry: UsageReportEntry; window: UsageWindow; display: UsageDisplay; @@ -207,6 +185,7 @@ function CardWindowBar({ return ( void; compact: boolean; @@ -236,12 +217,13 @@ function UsageRefreshButton({ const freshness = useMemo( () => ( ), - [fetchedAt], + [successfulAt, retained], ); return ( `, not the card. */ function UsageFreshness({ - fetchedAt, + successfulAt, + retained, style, testID, }: { - fetchedAt: string; + successfulAt: string | null; + retained: boolean; style: StyleProp; testID: string; }) { - const elapsed = useCompactTimeAgo(new Date(fetchedAt)); + const elapsed = useCompactTimeAgo(successfulAt ? new Date(successfulAt) : null); return ( - {formatUsageFreshness(elapsed)} + {successfulAt ? formatUsageFreshness(elapsed, retained) : "No successful update"} ); } diff --git a/packages/app/src/usage/format.test.ts b/packages/app/src/usage/format.test.ts index 88fe227ae6..22529c8d71 100644 --- a/packages/app/src/usage/format.test.ts +++ b/packages/app/src/usage/format.test.ts @@ -1,5 +1,5 @@ import { describe, expect, it } from "vitest"; -import { formatAmount } from "./format"; +import { formatAmount, formatResetLabel } from "./format"; describe("formatAmount", () => { it("groups thousands in the app's language", () => { @@ -13,3 +13,10 @@ describe("formatAmount", () => { expect(formatAmount(1234.5, "usd", "fr").replace(/\s/g, " ")).toBe("1 234,50 $US"); }); }); + +it("retained reset times that have passed do not claim the quota is resetting", () => { + const past = "2000-01-01T00:00:00.000Z"; + expect(formatResetLabel(past, true)).toBe("Reset time passed"); + expect(formatResetLabel(past)).toBe("resetting now"); + expect(formatResetLabel(null, true)).toBeNull(); +}); diff --git a/packages/app/src/usage/format.ts b/packages/app/src/usage/format.ts index 5adef2154d..e13a550e7b 100644 --- a/packages/app/src/usage/format.ts +++ b/packages/app/src/usage/format.ts @@ -27,10 +27,11 @@ function relativeDuration(iso: string): string | null { return `${diffMinutes}m`; } -export function formatResetLabel(iso: string | null | undefined): string | null { +export function formatResetLabel(iso: string | null | undefined, retained = false): string | null { if (!iso) return null; const rel = relativeDuration(iso); if (!rel) return null; + if (rel === "now" && retained) return "Reset time passed"; return rel === "now" ? "resetting now" : `resets ${rel}`; } diff --git a/packages/app/src/usage/model.test.ts b/packages/app/src/usage/model.test.ts index a2c493619d..13da42a6eb 100644 --- a/packages/app/src/usage/model.test.ts +++ b/packages/app/src/usage/model.test.ts @@ -1,5 +1,6 @@ import { describe, expect, it } from "vitest"; import { + resolveUsageReport, displayPercent, formatUsageFreshness, resolveAgentUsageView, @@ -325,3 +326,72 @@ describe("resolveAgentUsageView", () => { ).toEqual({ kind: "error", message: "Unable to load usage: Unknown agent" }); }); }); + +it("resolves retained usage and successful time without inventing old-daemon history", () => { + const success = entry({ windows: [{ id: "weekly", label: "Weekly", usedPct: 42 }] }); + const failure: UsageReportEntry = { + ...success, + fetchedAt: "2026-01-01T00:06:00.000Z", + report: { status: "error", error: "Rate limited" }, + lastSuccessful: { + fetchedAt: success.fetchedAt, + report: success.report as Extract, + }, + }; + expect(resolveUsageReport(failure)).toEqual({ + windows: success.report.status === "available" ? success.report.windows : [], + balances: [], + details: [], + planLabel: null, + successfulAt: success.fetchedAt, + retained: true, + messages: ["Rate limited"], + }); + expect(resolveUsageReport({ ...failure, lastSuccessful: undefined })).toEqual({ + windows: [], + balances: [], + details: [], + planLabel: null, + successfulAt: null, + retained: false, + messages: ["Rate limited"], + }); + expect(resolveUsageReport(success)).toEqual({ + windows: success.report.status === "available" ? success.report.windows : [], + balances: [], + details: [], + planLabel: null, + successfulAt: success.fetchedAt, + retained: false, + messages: [], + }); +}); + +it("orders failed polls by attempt time even when successful data is older", () => { + const success = entry({}); + if (success.report.status !== "available") throw new Error("fixture must be available"); + const failure: UsageReportEntry = { + ...success, + fetchedAt: "2026-01-01T00:06:00.000Z", + report: { status: "error", error: "Rate limited" }, + lastSuccessful: { fetchedAt: success.fetchedAt, report: success.report }, + }; + expect(upsertReport([failure], success)).toEqual([failure]); + expect(settleReports([failure], [success])).toEqual([failure]); + expect(upsertReport([success], failure)).toEqual([failure]); +}); + +it("available and retained usage show the same successful completion time", () => { + const success: UsageReportEntry = { ...entry({}), successfulAt: "2026-01-01T00:00:15.000Z" }; + if (success.report.status !== "available") throw new Error("fixture must be available"); + expect(resolveUsageReport(success).successfulAt).toBe("2026-01-01T00:00:15.000Z"); + const failure: UsageReportEntry = { + ...success, + successfulAt: undefined, + fetchedAt: "2026-01-01T00:06:00.000Z", + report: { status: "error", error: "Rate limited" }, + lastSuccessful: { fetchedAt: success.successfulAt!, report: success.report }, + }; + expect(resolveUsageReport(failure).successfulAt).toBe(resolveUsageReport(success).successfulAt); + expect(upsertReport([failure], success)).toEqual([failure]); +}); diff --git a/packages/app/src/usage/model.ts b/packages/app/src/usage/model.ts index ed8a39163a..1f1c82cce3 100644 --- a/packages/app/src/usage/model.ts +++ b/packages/app/src/usage/model.ts @@ -1,7 +1,7 @@ import { formatCompactTimeAgoAsProse } from "@/utils/time"; import { usageCopy } from "./copy"; import type { UsageDisplayAs } from "./preferences"; -import type { UsageReportEntry, UsageView, UsageWindow } from "./types"; +import type { UsageReport, UsageReportEntry, UsageView, UsageWindow } from "./types"; export function usedPercent(window: UsageWindow): number | null { if (window.usedPct != null) return window.usedPct; @@ -32,8 +32,8 @@ export function usageWindowRowLabel(input: { } /** When a report was fetched, from its compact relative time: "Updated 3m ago". */ -export function formatUsageFreshness(compactTimeAgo: string): string { - return `${usageCopy.updated} ${formatCompactTimeAgoAsProse(compactTimeAgo)}`; +export function formatUsageFreshness(compactTimeAgo: string, retained = false): string { + return `${retained ? "Last updated" : usageCopy.updated} ${formatCompactTimeAgoAsProse(compactTimeAgo)}`; } /** A user-requested refresh of one report. The previous report stays on screen throughout. */ @@ -192,3 +192,40 @@ export function resolveUsageModalHostId(choice: UsageHostChoice): string | null const picked = connected.find((host) => host.serverId === choice.pickedServerId); return picked?.serverId ?? resolveUsageHostId(choice) ?? connected[0]?.serverId ?? null; } + +/** Current outcome owns messages; only a successful poll owns values and freshness. */ +export function resolveUsageReport(entry: UsageReportEntry) { + const available = entry.report.status === "available"; + // COMPAT(usageLastSuccessful): added in v0.12.0, remove after 2027-04-17 once daemon floor >= v0.12.0. + // Older daemons cannot provide history; a failed attempt is never a successful update. + const snapshot = available ? null : (entry.lastSuccessful ?? null); + const content = entry.report.status === "available" ? entry.report : (snapshot?.report ?? null); + const messages: string[] = []; + if (!available) { + if (entry.loginErrors) + messages.push( + ...entry.loginErrors.map((login) => `${login.harness}: ${usageProblemText(login.report)}`), + ); + // COMPAT(usageLoginErrors): added in v0.11.0, remove after 2027-04-05 once daemon floor >= v0.11.0. + else messages.push(usageProblemText(entry.report)); + } + return { + windows: content?.windows ?? [], + balances: content?.balances ?? [], + details: content?.details ?? [], + planLabel: content?.planLabel ?? null, + // COMPAT(usageSuccessfulAt): added in v0.12.0, remove after 2027-04-17 once daemon floor >= v0.12.0. + // Old daemons expose only attempt time for available reports, never for failures. + successfulAt: available + ? (entry.successfulAt ?? entry.fetchedAt) + : (snapshot?.fetchedAt ?? null), + retained: snapshot !== null, + messages, + }; +} + +function usageProblemText(report: UsageReport): string { + if (report.status === "error") return report.error; + if (report.status === "unavailable") return usageCopy.problem(report.problem); + return ""; +} diff --git a/packages/app/src/usage/pinned.test.ts b/packages/app/src/usage/pinned.test.ts index 9965251595..8c2c2e58fd 100644 --- a/packages/app/src/usage/pinned.test.ts +++ b/packages/app/src/usage/pinned.test.ts @@ -257,9 +257,12 @@ describe("resolvePinnedUsage", () => { }); }); -it("keeps unavailable and error reports out of the sidebar summary", () => { +it("keeps unavailable and error reports out of the sidebar summary even with retained data", () => { + if (claude.report.status !== "available" || codex.report.status !== "available") + throw new Error("fixtures must be available"); const expired: UsageReportEntry = { ...claude, + lastSuccessful: { fetchedAt: claude.fetchedAt, report: claude.report }, report: { status: "unavailable", problem: { kind: "expired", expiresAt: "2026-10-01T00:00:00.000Z", refreshedBy: "claude" }, @@ -267,6 +270,7 @@ it("keeps unavailable and error reports out of the sidebar summary", () => { }; const failed: UsageReportEntry = { ...codex, + lastSuccessful: { fetchedAt: codex.fetchedAt, report: codex.report }, report: { status: "error", error: "Store deleted" }, }; expect(resolvePinnedUsage([expired, failed], preferences(null))).toEqual([]); diff --git a/packages/app/src/usage/window-bar.tsx b/packages/app/src/usage/window-bar.tsx index 5260a1c44b..79ea6b9f2d 100644 --- a/packages/app/src/usage/window-bar.tsx +++ b/packages/app/src/usage/window-bar.tsx @@ -26,7 +26,9 @@ export function UsageWindowBar({ onTogglePin, pinLabel, pinTestID, + retained = false, }: { + retained?: boolean; window: UsageWindow; displayAs: UsageDisplayAs; /** Whether the row pins the window to the sidebar. When false the row is a plain bar. */ @@ -40,10 +42,13 @@ export function UsageWindowBar({ const shownPct = displayPercent(window, displayAs); const tone = windowTone(window); - const isAtRisk = window.runsOutAt != null && window.shortfallPct != null; + const isAtRisk = + window.runsOutAt != null && + window.shortfallPct != null && + (!retained || Date.parse(window.runsOutAt) > Date.now()); const trailing = isAtRisk ? `runs out ${formatResetLabel(window.runsOutAt)?.replace("resets ", "") ?? ""}`.trim() - : formatResetLabel(window.resetsAt); + : formatResetLabel(window.resetsAt, retained); const value = shownPct != null ? formatDisplayPct(shownPct, displayAs) : "—"; const accessibilityState = useMemo(() => ({ checked: pinned }), [pinned]); diff --git a/packages/app/src/utils/projects.ts b/packages/app/src/utils/projects.ts index f5ee1142c4..647561c56f 100644 --- a/packages/app/src/utils/projects.ts +++ b/packages/app/src/utils/projects.ts @@ -13,6 +13,7 @@ export interface WorkspaceSummary { archivingAt?: string; /** Pull/merge request number backing this workspace, so a query can find it. */ changeRequestNumber: number | null; + statusEnteredAt: Date | null; } export interface ProjectHostEntry { @@ -161,6 +162,7 @@ function toWorkspaceSummary(workspace: WorkspaceDescriptor): WorkspaceSummary { currentBranch: currentBranch && currentBranch !== "HEAD" ? currentBranch : null, ...(workspace.archivingAt ? { archivingAt: workspace.archivingAt } : {}), changeRequestNumber: toChangeRequestNumber(workspace), + statusEnteredAt: workspace.statusEnteredAt, }; } diff --git a/packages/app/src/utils/sidebar-project-row-model.test.ts b/packages/app/src/utils/sidebar-project-row-model.test.ts index de23319c97..a2978a669c 100644 --- a/packages/app/src/utils/sidebar-project-row-model.test.ts +++ b/packages/app/src/utils/sidebar-project-row-model.test.ts @@ -65,6 +65,45 @@ function project(overrides: ProjectOverrides = {}): SidebarProjectEntry { } describe("buildSidebarProjectRowModel", () => { + it("prefers the active host when the grouped project can create there", () => { + const result = buildSidebarProjectRowModel({ + project: project({ + hosts: [ + { serverId: "host-a", iconWorkingDir: "/repo/a", worktreeSupport: "supported" }, + { serverId: "host-b", iconWorkingDir: "/repo/b", worktreeSupport: "supported" }, + ], + }), + collapsed: false, + preferredServerId: "host-b", + }); + + expect(result.trailingAction).toEqual({ + kind: "new_workspace", + target: { serverId: "host-b", projectId: "project-host-b", iconWorkingDir: "/repo/b" }, + }); + }); + + it.each(["host-b", "another-host"])( + "keeps the first eligible placement when preferred host %s cannot create here", + (preferredServerId) => { + const result = buildSidebarProjectRowModel({ + project: project({ + hosts: [ + { serverId: "host-a", iconWorkingDir: "/repo/a", worktreeSupport: "supported" }, + { serverId: "host-b", iconWorkingDir: "/repo/b", worktreeSupport: "unsupported" }, + ], + }), + collapsed: false, + preferredServerId, + }); + + expect(result.trailingAction).toEqual({ + kind: "new_workspace", + target: { serverId: "host-a", projectId: "project-host-a", iconWorkingDir: "/repo/a" }, + }); + }, + ); + it("renders a non-git single-workspace project as an expandable section", () => { const result = buildSidebarProjectRowModel({ project: project({ diff --git a/packages/app/src/utils/sidebar-project-row-model.ts b/packages/app/src/utils/sidebar-project-row-model.ts index 619e08dc4f..d5504d08bb 100644 --- a/packages/app/src/utils/sidebar-project-row-model.ts +++ b/packages/app/src/utils/sidebar-project-row-model.ts @@ -85,7 +85,9 @@ export function resolveSidebarProjectLocalPath( function resolveNewWorkspaceTarget( project: SidebarProjectEntry, supportsMultiplicityByServerId: ReadonlyMap, + preferredServerId: string | null | undefined, ): SidebarProjectHostTarget | null { + let fallbackTarget: SidebarProjectHostTarget | null = null; for (const host of project.hosts) { if ( host.worktreeSupport === "unsupported" && @@ -94,22 +96,30 @@ function resolveNewWorkspaceTarget( continue; } const target = hostTarget(host); - if (target) return target; + if (!target) continue; + if (host.serverId === preferredServerId) return target; + fallbackTarget ??= target; } - return null; + return fallbackTarget; } function projectTrailingAction( project: SidebarProjectEntry, supportsMultiplicityByServerId: ReadonlyMap, + preferredServerId: string | null | undefined, ): SidebarProjectTrailingAction { - const target = resolveNewWorkspaceTarget(project, supportsMultiplicityByServerId); + const target = resolveNewWorkspaceTarget( + project, + supportsMultiplicityByServerId, + preferredServerId, + ); return target ? { kind: "new_workspace", target } : { kind: "none" }; } export function buildSidebarProjectRowModel(input: { project: SidebarProjectEntry; collapsed: boolean; + preferredServerId?: string | null; supportsMultiplicityByServerId?: ReadonlyMap; }): SidebarProjectRowModel { return { @@ -118,6 +128,7 @@ export function buildSidebarProjectRowModel(input: { trailingAction: projectTrailingAction( input.project, input.supportsMultiplicityByServerId ?? EMPTY_MULTIPLICITY_MAP, + input.preferredServerId, ), }; } diff --git a/packages/app/src/utils/tool-call-icon-name.test.ts b/packages/app/src/utils/tool-call-icon-name.test.ts index 14da899c39..272422ecbd 100644 --- a/packages/app/src/utils/tool-call-icon-name.test.ts +++ b/packages/app/src/utils/tool-call-icon-name.test.ts @@ -53,4 +53,14 @@ describe("resolveToolCallIconName", () => { expect(icon).toBe("wrench"); }); + + it("uses the Paseo icon for agent messages despite the legacy bot detail icon", () => { + const icon = resolveToolCallIconName( + "agent_message", + { type: "plain_text", text: "Done.", icon: "bot" }, + { event: "finished", sender: { id: "agt_1" }, text: "Done." }, + ); + + expect(icon).toBe("paseo"); + }); }); diff --git a/packages/app/src/utils/tool-call-icon-name.ts b/packages/app/src/utils/tool-call-icon-name.ts index 28bfedb700..f5fb12559d 100644 --- a/packages/app/src/utils/tool-call-icon-name.ts +++ b/packages/app/src/utils/tool-call-icon-name.ts @@ -1,3 +1,4 @@ +import type { AgentMessage } from "@getpaseo/protocol/agent-message"; import type { ToolCallDetail, ToolCallIconName } from "@getpaseo/protocol/agent-types"; import { isPaseoToolName } from "@getpaseo/protocol/tool-name-normalization"; @@ -17,7 +18,15 @@ const TOOL_DETAIL_ICON_NAMES: Record = { unknown: "wrench", }; -export function resolveToolCallIconName(toolName: string, detail?: ToolCallDetail): ToolCallIcon { +export function resolveToolCallIconName( + toolName: string, + detail?: ToolCallDetail, + agentMessage?: AgentMessage, +): ToolCallIcon { + // Agent messages are Paseo deliveries; the wire detail's legacy "bot" icon is for old clients. + if (agentMessage) { + return "paseo"; + } const lowerName = toolName.trim().toLowerCase(); if (detail?.type === "plain_text" && detail.icon) { diff --git a/packages/app/src/utils/tool-call-icon.ts b/packages/app/src/utils/tool-call-icon.ts index 804b68c4ca..4e1d83e040 100644 --- a/packages/app/src/utils/tool-call-icon.ts +++ b/packages/app/src/utils/tool-call-icon.ts @@ -10,6 +10,7 @@ import { SquareTerminal, Wrench, } from "lucide-react-native"; +import type { AgentMessage } from "@getpaseo/protocol/agent-message"; import type { ToolCallDetail } from "@getpaseo/protocol/agent-types"; import { PaseoLogo } from "@/components/icons/paseo-logo"; import { resolveToolCallIconName, type ToolCallIcon } from "./tool-call-icon-name"; @@ -36,6 +37,7 @@ export function componentForToolCallIcon(name: ToolCallIcon): ToolCallIconCompon export function resolveToolCallIcon( toolName: string, detail?: ToolCallDetail, + agentMessage?: AgentMessage, ): ToolCallIconComponent { - return componentForToolCallIcon(resolveToolCallIconName(toolName, detail)); + return componentForToolCallIcon(resolveToolCallIconName(toolName, detail, agentMessage)); } diff --git a/packages/app/src/workspace-tabs/agent-visibility.test.ts b/packages/app/src/workspace-tabs/agent-visibility.test.ts index 3b16c6b8d5..59f96fccbc 100644 --- a/packages/app/src/workspace-tabs/agent-visibility.test.ts +++ b/packages/app/src/workspace-tabs/agent-visibility.test.ts @@ -1,7 +1,9 @@ -import { describe, expect, it } from "vitest"; -import type { Agent } from "@/stores/session-store"; +import type { DaemonClient } from "@getpaseo/client/internal/daemon-client"; +import { afterEach, describe, expect, it } from "vitest"; +import { useSessionStore, type Agent } from "@/stores/session-store"; import { buildWorkspaceTabSnapshot, + createWorkspaceAgentVisibilitySelector, deriveWorkspaceAgentVisibility, shouldPruneWorkspaceAgentTab, workspaceAgentVisibilityEqual, @@ -336,6 +338,139 @@ describe("workspace agent visibility", () => { }); }); + describe("createWorkspaceAgentVisibilitySelector", () => { + const SERVER_ID = "srv"; + + class IterationCountingMap extends Map { + iterations = 0; + override values() { + this.iterations += 1; + return super.values(); + } + override entries() { + this.iterations += 1; + return super.entries(); + } + override [Symbol.iterator]() { + this.iterations += 1; + return super[Symbol.iterator](); + } + } + + function seedSession(agents: Map): void { + useSessionStore.getState().initializeSession(SERVER_ID, null as unknown as DaemonClient); + useSessionStore.getState().setAgents(SERVER_ID, agents); + } + + function streamTick(text: string): void { + useSessionStore.getState().setAgentStreamState(SERVER_ID, "parent-agent", { + head: [ + { + kind: "assistant_message", + id: "message-1", + text, + timestamp: new Date("2026-03-04T00:02:00.000Z"), + }, + ], + }); + } + + const parent = makeAgent({ id: "parent-agent", cwd: "/repo", workspaceId: WORKSPACE_ID }); + const child = makeAgent({ + id: "child-agent", + cwd: "/repo", + workspaceId: WORKSPACE_ID, + parentAgentId: parent.id, + }); + const otherWorkspace = makeAgent({ id: "other-agent", cwd: "/other", workspaceId: "ws-2" }); + + afterEach(() => { + useSessionStore.getState().clearSession(SERVER_ID); + }); + + it("returns the cached result without walking agents when a stream tick leaves them unchanged", () => { + const agents = new IterationCountingMap([ + [parent.id, parent], + [otherWorkspace.id, otherWorkspace], + ]); + seedSession(agents); + const select = createWorkspaceAgentVisibilitySelector({ + serverId: SERVER_ID, + workspaceId: WORKSPACE_ID, + }); + const before = select(useSessionStore.getState()); + const iterationsAfterFirstSelect = agents.iterations; + + for (let tick = 0; tick < 100; tick += 1) { + streamTick(`token ${tick}`); + expect(select(useSessionStore.getState())).toBe(before); + } + + expect(useSessionStore.getState().sessions[SERVER_ID]?.agents).toBe(agents); + expect(agents.iterations).toBe(iterationsAfterFirstSelect); + expect(before.activeAgentIds).toEqual(new Set([parent.id])); + }); + + it("recomputes when the agents map changes", () => { + const agents = new Map([[parent.id, parent]]); + seedSession(agents); + const select = createWorkspaceAgentVisibilitySelector({ + serverId: SERVER_ID, + workspaceId: WORKSPACE_ID, + }); + const before = select(useSessionStore.getState()); + + useSessionStore.getState().setAgents(SERVER_ID, new Map(agents).set(child.id, child)); + const after = select(useSessionStore.getState()); + + expect(after).not.toBe(before); + expect(after.activeAgentIds).toEqual(new Set([parent.id, child.id])); + expect(after.autoOpenAgentIds).toEqual(new Set([parent.id])); + }); + + it("keeps the previous result when a changed agents map yields the same sets", () => { + const agents = new Map([ + [parent.id, parent], + [otherWorkspace.id, otherWorkspace], + ]); + seedSession(agents); + const select = createWorkspaceAgentVisibilitySelector({ + serverId: SERVER_ID, + workspaceId: WORKSPACE_ID, + }); + const before = select(useSessionStore.getState()); + + useSessionStore + .getState() + .setAgents( + SERVER_ID, + new Map(agents).set(otherWorkspace.id, { ...otherWorkspace, title: "Renamed" }), + ); + + expect(select(useSessionStore.getState())).toBe(before); + }); + + it("recomputes when agent details reveal a parent in another workspace", () => { + seedSession(new Map([[child.id, child]])); + const select = createWorkspaceAgentVisibilitySelector({ + serverId: SERVER_ID, + workspaceId: WORKSPACE_ID, + }); + expect(select(useSessionStore.getState()).autoOpenAgentIds).toEqual(new Set()); + + useSessionStore + .getState() + .setAgentDetails( + SERVER_ID, + new Map([[parent.id, { ...parent, workspaceId: "ws-parent" }]]), + ); + const after = select(useSessionStore.getState()); + + expect(after.activeAgentIds).toEqual(new Set([child.id])); + expect(after.autoOpenAgentIds).toEqual(new Set([child.id])); + }); + }); + describe("workspaceAgentVisibilityEqual", () => { it("returns true for identical sets", () => { const a = { diff --git a/packages/app/src/workspace-tabs/agent-visibility.ts b/packages/app/src/workspace-tabs/agent-visibility.ts index 399b786ef6..3dd1881643 100644 --- a/packages/app/src/workspace-tabs/agent-visibility.ts +++ b/packages/app/src/workspace-tabs/agent-visibility.ts @@ -28,17 +28,15 @@ export function deriveWorkspaceAgentVisibility(input: { const activeAgentIds = new Set(); const autoOpenAgentIds = new Set(); - const agentsById = new Map([ - ...(agentDetails?.entries() ?? []), - ...(sessionAgents?.entries() ?? []), - ]); for (const agent of sessionAgents?.values() ?? []) { if (!agentBelongsToWorkspace(agent, workspaceId)) { continue; } if (!agent.archivedAt) { activeAgentIds.add(agent.id); - const parentAgent = agent.parentAgentId ? agentsById.get(agent.parentAgentId) : undefined; + const parentAgent = agent.parentAgentId + ? (sessionAgents?.get(agent.parentAgentId) ?? agentDetails?.get(agent.parentAgentId)) + : undefined; if (isWorkspaceRootAgent(agent, parentAgent)) { autoOpenAgentIds.add(agent.id); } @@ -47,6 +45,46 @@ export function deriveWorkspaceAgentVisibility(input: { return { activeAgentIds, autoOpenAgentIds }; } +interface AgentMapsSnapshot { + sessions: Record< + string, + { agents: Map; agentDetails: Map } | undefined + >; +} + +// Session-store selectors run on every store update, including every stream tick, which +// leaves the agent maps untouched. Reuse the previous result until either map changes, and +// keep it when a recompute yields the same sets so the hook's equality check stays O(1). +export function createWorkspaceAgentVisibilitySelector(input: { + serverId: string; + workspaceId: string | null | undefined; +}): (state: AgentMapsSnapshot) => WorkspaceAgentVisibility { + let previousAgents: Map | undefined; + let previousAgentDetails: Map | undefined; + let previousVisibility: WorkspaceAgentVisibility | null = null; + + return (state) => { + const session = state.sessions[input.serverId]; + const agents = session?.agents; + const agentDetails = session?.agentDetails; + if (previousVisibility && agents === previousAgents && agentDetails === previousAgentDetails) { + return previousVisibility; + } + + const visibility = deriveWorkspaceAgentVisibility({ + sessionAgents: agents, + agentDetails, + workspaceId: input.workspaceId, + }); + previousAgents = agents; + previousAgentDetails = agentDetails; + if (!previousVisibility || !workspaceAgentVisibilityEqual(previousVisibility, visibility)) { + previousVisibility = visibility; + } + return previousVisibility; + }; +} + export function buildWorkspaceTabSnapshot(input: { agentVisibility: WorkspaceAgentVisibility; agentsHydrated: boolean; @@ -73,8 +111,9 @@ export function workspaceAgentVisibilityEqual( b: WorkspaceAgentVisibility, ): boolean { return ( - setsEqual(a.activeAgentIds, b.activeAgentIds) && - setsEqual(a.autoOpenAgentIds, b.autoOpenAgentIds) + a === b || + (setsEqual(a.activeAgentIds, b.activeAgentIds) && + setsEqual(a.autoOpenAgentIds, b.autoOpenAgentIds)) ); } diff --git a/packages/app/src/workspace-tabs/launcher/index.tsx b/packages/app/src/workspace-tabs/launcher/index.tsx index ea983b4bd8..afbefcb042 100644 --- a/packages/app/src/workspace-tabs/launcher/index.tsx +++ b/packages/app/src/workspace-tabs/launcher/index.tsx @@ -11,7 +11,7 @@ import { useTranslation } from "react-i18next"; import { Globe, SquarePen, SquareTerminal } from "lucide-react-native"; import invariant from "tiny-invariant"; import { useDaemonConfig } from "@/hooks/use-daemon-config"; -import { resolvePluginIcon } from "@/plugins/icons"; +import { pluginIconComponent } from "@/plugins/icons"; import { useInstalledPlugins } from "@/plugins/registry"; import { pluginPanelSupportsLocation } from "@/plugins/workspace-panels/locations"; import { buildSettingsHostSectionRoute } from "@/utils/host-routes"; @@ -212,7 +212,7 @@ export function useWorkspaceTabLaunchCatalog(input: { pluginItems.push({ id: `plugin:${plugin.id}:${panel.id}`, label: panel.title, - Icon: resolvePluginIcon(panel.icon), + Icon: pluginIconComponent(panel.icon), disabled: false, panelKind: "plugin", launch: launchSelection(selection), diff --git a/packages/cli/package.json b/packages/cli/package.json index bebedc5c93..a4bacd86fa 100644 --- a/packages/cli/package.json +++ b/packages/cli/package.json @@ -1,6 +1,6 @@ { "name": "@getpaseo/cli", - "version": "0.12.0-beta.1", + "version": "0.12.0", "description": "Paseo CLI - control your AI coding agents from the command line", "bin": { "paseo": "bin/paseo" @@ -28,9 +28,9 @@ }, "dependencies": { "@clack/prompts": "^1.0.0", - "@getpaseo/client": "0.12.0-beta.1", - "@getpaseo/protocol": "0.12.0-beta.1", - "@getpaseo/server": "0.12.0-beta.1", + "@getpaseo/client": "0.12.0", + "@getpaseo/protocol": "0.12.0", + "@getpaseo/server": "0.12.0", "chalk": "^5.3.0", "commander": "^12.0.0", "mime-types": "^2.1.35", diff --git a/packages/cli/src/commands/usage/index.test.ts b/packages/cli/src/commands/usage/index.test.ts index 9c2e3e8bbf..d6d5b62ee1 100644 --- a/packages/cli/src/commands/usage/index.test.ts +++ b/packages/cli/src/commands/usage/index.test.ts @@ -277,3 +277,40 @@ describe("usage CLI registration", () => { expect(usage.commands[1]!.helpInformation()).toContain(""); }); }); + +it("shows retained values with current failures and separates successful time from latest attempt", async () => { + const success: UsageReportEntry = { ...reports[0]!, successfulAt: "2026-10-09T12:00:15Z" }; + const current = await runUsageCommand( + options, + { kind: "inspect", id: success.id }, + host([success]).connect, + ); + expect(render(current)).toContain("Latest attempt: 2026-10-09T12:00:00Z"); + expect(render(current)).toContain("Last successful: 2026-10-09T12:00:15Z"); + const currentList = await runUsageCommand(options, { kind: "list" }, host([success]).connect); + expect(render(currentList)).toContain("Last successful: 2026-10-09T12:00:15Z"); + if (success.report.status !== "available") throw new Error("fixture must be available"); + const retained: UsageReportEntry = { + ...success, + fetchedAt: "2026-10-09T12:06:00Z", + report: { status: "error", error: "Rate limited" }, + successfulAt: undefined, + lastSuccessful: { fetchedAt: success.successfulAt!, report: success.report }, + }; + const daemon = host([retained]); + const listed = await runUsageCommand(options, { kind: "list" }, daemon.connect); + expect(render(listed)).toContain("Retained: Five hours: 12.5% used"); + expect(render(listed)).toContain("Last successful: 2026-10-09T12:00:15Z"); + expect(render(listed)).toContain("Rate limited"); + expect(JSON.parse(render(listed, { format: "json" }))).toEqual([retained]); + const inspected = await runUsageCommand( + options, + { kind: "inspect", id: retained.id }, + daemon.connect, + ); + expect(render(inspected)).toContain("Latest attempt: 2026-10-09T12:06:00Z"); + expect(render(inspected)).toContain("Last successful: 2026-10-09T12:00:15Z"); + expect(render(inspected)).toContain("Retained usage:"); + expect(render(inspected)).toContain("Five hours: 12.5% used"); + expect(render(inspected)).toContain("Reason: Rate limited"); +}); diff --git a/packages/cli/src/commands/usage/presentation.ts b/packages/cli/src/commands/usage/presentation.ts index ecc4aba405..2ecadafc59 100644 --- a/packages/cli/src/commands/usage/presentation.ts +++ b/packages/cli/src/commands/usage/presentation.ts @@ -44,8 +44,18 @@ function summary(entry: UsageReportEntry): string[] { const lines = [failureText(report)]; for (const login of entry.loginErrors ?? []) lines.push(`${login.harness}: ${failureText(login.report)}`); + if (entry.lastSuccessful) { + lines.push(`Last successful: ${entry.lastSuccessful.fetchedAt}`); + lines.push( + ...availableSummary(entry.lastSuccessful.report).map((line) => `Retained: ${line}`), + ); + } else lines.push("No successful update"); return lines; } + return [...availableSummary(report), `Last successful: ${successfulTime(entry)}`]; +} + +function availableSummary(report: Extract): string[] { const lines = report.windows.map(windowText); lines.push(...(report.balances ?? []).map(balanceText)); return lines.length ? lines : ["-"]; @@ -68,7 +78,7 @@ const summarySchema: OutputSchema = { { header: "ACCOUNT", field: "account" }, { header: "STATUS", field: "status" }, { header: "USAGE", field: "usage" }, - { header: "FETCHED", field: "fetched" }, + { header: "FETCHED (LATEST ATTEMPT)", field: "fetched" }, ], }; @@ -79,30 +89,15 @@ function inspect(entry: UsageReportEntry): string { `Source ID: ${entry.sourceId}`, `Account: ${value(entry.account.label)}`, `Status: ${entry.report.status}`, - `Fetched: ${value(entry.fetchedAt)}`, + `Latest attempt: ${value(entry.fetchedAt)}`, ]; - const { report } = entry; - if (report.status === "available") { - lines.push(`Plan: ${value(report.planLabel)}`, "Windows:"); - if (!report.windows.length) lines.push(" -"); - for (const window of report.windows) { - lines.push(` ${windowText(window)} [${window.id}]`, ` Resets: ${value(window.resetsAt)}`); - if (window.runsOutAt != null) lines.push(` Runs out: ${window.runsOutAt}`); - if (window.shortfallPct != null) lines.push(` Shortfall: ${percent(window.shortfallPct)}`); - } - lines.push("Balances:"); - if (!report.balances?.length) lines.push(" -"); - for (const balance of report.balances ?? []) { - lines.push( - ` ${balanceText(balance)} [${balance.id}]`, - ` Resets: ${value(balance.resetsAt)}`, - ); - } - lines.push("Details:"); - if (!report.details?.length) lines.push(" -"); - for (const detail of report.details ?? []) lines.push(` ${detail.label}: ${detail.value}`); - } else { - lines.push(`Reason: ${failureText(report)}`); + const report = entry.report.status === "available" ? entry.report : entry.lastSuccessful?.report; + const successfulAt = successfulTime(entry); + lines.push(successfulAt ? `Last successful: ${successfulAt}` : "No successful update"); + if (entry.report.status !== "available") lines.push(`Reason: ${failureText(entry.report)}`); + if (report) { + if (entry.report.status !== "available") lines.push("Retained usage:"); + lines.push(...availableDetails(report)); } if (entry.loginErrors?.length) { lines.push("Login failures:"); @@ -135,3 +130,33 @@ export const usageSchema: OutputSchema = { return renderTable({ type: "list", data: rows, schema: summarySchema }, options); }, }; + +function availableDetails(report: Extract): string[] { + const lines: string[] = []; + lines.push(`Plan: ${value(report.planLabel)}`, "Windows:"); + if (!report.windows.length) lines.push(" -"); + for (const window of report.windows) { + lines.push(` ${windowText(window)} [${window.id}]`, ` Resets: ${value(window.resetsAt)}`); + if (window.runsOutAt != null) lines.push(` Runs out: ${window.runsOutAt}`); + if (window.shortfallPct != null) lines.push(` Shortfall: ${percent(window.shortfallPct)}`); + } + lines.push("Balances:"); + if (!report.balances?.length) lines.push(" -"); + for (const balance of report.balances ?? []) { + lines.push( + ` ${balanceText(balance)} [${balance.id}]`, + ` Resets: ${value(balance.resetsAt)}`, + ); + } + lines.push("Details:"); + if (!report.details?.length) lines.push(" -"); + for (const detail of report.details ?? []) lines.push(` ${detail.label}: ${detail.value}`); + return lines; +} + +function successfulTime(entry: UsageReportEntry): string | undefined { + // COMPAT(usageSuccessfulAt): added in v0.12.0, remove after 2027-04-17 once daemon floor >= v0.12.0. + // Only available reports from older daemons can use their attempt timestamp as freshness. + if (entry.report.status === "available") return entry.successfulAt ?? entry.fetchedAt; + return entry.lastSuccessful?.fetchedAt; +} diff --git a/packages/client/package.json b/packages/client/package.json index b10a452edd..07ba43b332 100644 --- a/packages/client/package.json +++ b/packages/client/package.json @@ -1,6 +1,6 @@ { "name": "@getpaseo/client", - "version": "0.12.0-beta.1", + "version": "0.12.0", "description": "Paseo client SDK package", "files": [ "dist", @@ -39,8 +39,8 @@ "test": "vitest run" }, "dependencies": { - "@getpaseo/protocol": "0.12.0-beta.1", - "@getpaseo/relay": "0.12.0-beta.1", + "@getpaseo/protocol": "0.12.0", + "@getpaseo/relay": "0.12.0", "zod": "^4.4.3" }, "devDependencies": { diff --git a/packages/client/src/connection/index.ts b/packages/client/src/connection/index.ts index d939b3c72b..eda2fec26b 100644 --- a/packages/client/src/connection/index.ts +++ b/packages/client/src/connection/index.ts @@ -141,6 +141,7 @@ export const DEFAULT_CLIENT_CAPABILITIES = { [CLIENT_CAPS.timelineNotifications]: true, [CLIENT_CAPS.pluginTimelineItems]: true, [CLIENT_CAPS.workspaceSetupBlocked]: true, + [CLIENT_CAPS.workspaceSetupObservation]: true, [CLIENT_CAPS.explicitEventSubscriptions]: true, } satisfies Record, true>; diff --git a/packages/client/src/daemon-client.test.ts b/packages/client/src/daemon-client.test.ts index 6b82922841..7469470ad1 100644 --- a/packages/client/src/daemon-client.test.ts +++ b/packages/client/src/daemon-client.test.ts @@ -1038,6 +1038,7 @@ test("advertises client capabilities in hello", async () => { timeline_notifications: true, plugin_timeline_items: true, workspace_setup_blocked: true, + workspace_setup_observation: true, hello_rejection: true, browser_host: { supportedCommands: ["list_tabs"], diff --git a/packages/client/src/daemon-client.ts b/packages/client/src/daemon-client.ts index e0e4d9ddc5..647e1fddf6 100644 --- a/packages/client/src/daemon-client.ts +++ b/packages/client/src/daemon-client.ts @@ -12,7 +12,7 @@ import { CreationClient } from "./creation/index.js"; import type { CreationSnapshot } from "@getpaseo/protocol/messages"; import type { z } from "zod"; import type { SessionEventSubscription } from "@getpaseo/protocol/messages"; -import type { ClientCapability } from "@getpaseo/protocol/client-capabilities"; +import { CLIENT_CAPS, type ClientCapability } from "@getpaseo/protocol/client-capabilities"; import type { AgentAttentionNotificationPayload } from "@getpaseo/protocol/agent-attention-notification"; import { MAX_WEBSOCKET_MESSAGE_BYTES } from "@getpaseo/protocol/websocket-message-limit"; import { @@ -2313,6 +2313,8 @@ export class DaemonClient { message, async (query, accept) => { resetSource = false; + if (query.type === "workspace.setup.subscribe.request") + this.requireWorkspaceSetupObservation(); const requestId = this.createRequestId(options?.requestId); const request = SessionInboundMessageSchema.parse({ ...query, requestId }); try { @@ -2781,6 +2783,27 @@ export class DaemonClient { }); } + observeWorkspaceSetup( + workspaceId: string, + options?: { signal?: AbortSignal }, + ): OwnedSubscription> { + return this.observe( + "workspace.setup.subscribe.response", + { type: "workspace.setup.subscribe.request", workspaceId }, + options, + ); + } + + private requireWorkspaceSetupObservation(): void { + if ( + this.lastServerInfoMessage?.features?.workspaceSetupObservation !== true || + this.lastServerInfoMessage.features.ownedSubscriptions !== true || + this.config.capabilities?.[CLIENT_CAPS.workspaceSetupObservation] === false || + this.config.capabilities?.[CLIENT_CAPS.ownedSubscriptions] === false + ) + throw new Error("Update the host to view workspace setup details"); + } + async fetchWorkspaceSetupStatus( workspaceId: string, requestId?: string, diff --git a/packages/desktop/e2e/keyboard-shortcut-unassign.spec.ts b/packages/desktop/e2e/keyboard-shortcut-unassign.spec.ts index b7063b4565..86aef1b880 100644 --- a/packages/desktop/e2e/keyboard-shortcut-unassign.spec.ts +++ b/packages/desktop/e2e/keyboard-shortcut-unassign.spec.ts @@ -261,3 +261,35 @@ test("rebinding Jump to tab preserves the number group after reload", async ({ await openSettingsSection(page, "shortcuts"); await expectTabNumberRange(page); }); + +async function expectNumberRequiredBeforeSaving(page: Page, label: string) { + const row = page.getByText(label, { exact: true }).locator(".."); + await expect(row.getByRole("button", { name: "Done", exact: true })).toBeDisabled(); + await expect(row.getByText("End with a number from 1 to 9.", { exact: true })).toBeVisible(); +} + +async function completeNumberShortcut(page: Page, label: string) { + const row = page.getByText(label, { exact: true }).locator(".."); + await page.keyboard.press("Backspace"); + await page.keyboard.press("Control+2"); + await expect(row.getByRole("button", { name: "Done", exact: true })).toBeEnabled(); + await row.getByRole("button", { name: "Done", exact: true }).click(); + await expect(row.getByText("⌃K", { exact: true })).toBeVisible(); + await expect(row.getByText("⌃1-9", { exact: true })).toBeVisible(); +} + +for (const { label, action } of [ + { label: "Jump to tab", action: "workspace-tab-jump-index" }, + { label: "Jump to workspace", action: "workspace-jump-index" }, +]) { + test(`${label} requires a final number before a recorded shortcut can be saved`, async ({ + page, + }) => { + await openShortcutsSettings(page); + await captureShortcut(page, label, action, "Control+K"); + await expectNumberRequiredBeforeSaving(page, label); + await page.keyboard.press("Control+0"); + await expectNumberRequiredBeforeSaving(page, label); + await completeNumberShortcut(page, label); + }); +} diff --git a/packages/desktop/e2e/workspace-restart.spec.ts b/packages/desktop/e2e/workspace-restart.spec.ts index 67bc8408ea..9f01b351f6 100644 --- a/packages/desktop/e2e/workspace-restart.spec.ts +++ b/packages/desktop/e2e/workspace-restart.spec.ts @@ -232,17 +232,18 @@ test("scrolled chat does not exclude the workspace titlebar from dragging", asyn } await page.getByRole("button", { name: "Close Find", exact: true }).click(); await expect(find).toBeHidden(); + // Closing Find returns keyboard scrolling to the chat viewport, which emits no window region. await expect - .poll(() => - chat.evaluate((scroll) => ({ - focusReturned: document.activeElement?.contains(scroll), - tabindex: document.activeElement?.getAttribute("tabindex"), - appRegion: getComputedStyle(document.activeElement!).getPropertyValue( - "-webkit-app-region", - ), - })), - ) - .toEqual({ focusReturned: true, tabindex: "-1", appRegion: "no-drag" }); + .poll(() => chat.evaluate((scroll) => document.activeElement === scroll)) + .toBe(true); + await expect + .poll(() => chat.evaluate(inspectChatDragExclusions)) + .toEqual({ + contentCrossesHeader: true, + contentCrossesTabRow: true, + focusScopeRegion: "no-drag", + exclusions: 0, + }); await page.screenshot({ path: testInfo.outputPath("scrolled-chat-titlebar.png") }); } finally { await agent.cleanup(); diff --git a/packages/desktop/package.json b/packages/desktop/package.json index ac128ee180..1c8cc7687e 100644 --- a/packages/desktop/package.json +++ b/packages/desktop/package.json @@ -1,6 +1,6 @@ { "name": "@getpaseo/desktop", - "version": "0.12.0-beta.1", + "version": "0.12.0", "private": true, "description": "Paseo desktop app (Electron wrapper)", "homepage": "https://paseo.sh", diff --git a/packages/expo-two-way-audio/package.json b/packages/expo-two-way-audio/package.json index 9e49135e39..83006f32a2 100644 --- a/packages/expo-two-way-audio/package.json +++ b/packages/expo-two-way-audio/package.json @@ -1,6 +1,6 @@ { "name": "@getpaseo/expo-two-way-audio", - "version": "0.12.0-beta.1", + "version": "0.12.0", "description": "Native module for two way audio streaming", "keywords": [ "ExpoTwoWayAudio", diff --git a/packages/highlight/package.json b/packages/highlight/package.json index 2e3a55146c..696325f4f7 100644 --- a/packages/highlight/package.json +++ b/packages/highlight/package.json @@ -1,6 +1,6 @@ { "name": "@getpaseo/highlight", - "version": "0.12.0-beta.1", + "version": "0.12.0", "files": [ "dist", "!dist/**/*.map", diff --git a/packages/plugin/package.json b/packages/plugin/package.json index a7354bc086..0162b085f3 100644 --- a/packages/plugin/package.json +++ b/packages/plugin/package.json @@ -1,6 +1,6 @@ { "name": "@getpaseo/plugin", - "version": "0.12.0-beta.1", + "version": "0.12.0", "description": "Paseo plugin SDK package", "files": [ "dist", @@ -70,8 +70,8 @@ "use-sync-external-store": "^1.6.0" }, "devDependencies": { - "@getpaseo/client": "0.12.0-beta.1", - "@getpaseo/protocol": "0.12.0-beta.1", + "@getpaseo/client": "0.12.0", + "@getpaseo/protocol": "0.12.0", "@types/node": "^20.9.0", "@types/react": "~19.2.0", "react": "19.1.0", @@ -81,8 +81,8 @@ "zod": "^4.4.3" }, "peerDependencies": { - "@getpaseo/client": "0.12.0-beta.1", - "@getpaseo/protocol": "0.12.0-beta.1", + "@getpaseo/client": "0.12.0", + "@getpaseo/protocol": "0.12.0", "react": "~19.1.0", "react-native": ">=0.81.5", "zod": "^4.4.3" diff --git a/packages/plugin/src/client/buttons.ts b/packages/plugin/src/client/buttons.ts index f5272e7ae4..76e5531143 100644 --- a/packages/plugin/src/client/buttons.ts +++ b/packages/plugin/src/client/buttons.ts @@ -1,16 +1,16 @@ import type { ComponentType } from "react"; -import type { PluginHostProps } from "./contracts.js"; +import type { PluginIconProps } from "../icons.js"; +import type { PluginHostProps, PluginIcon } from "./contracts.js"; export type PluginButtonContext = | { context: "workspace"; workspaceId: string } | { context: "agent"; workspaceId: string; agentId: string }; -export type PluginButtonIconProps = PluginHostProps & - PluginButtonContext & { size: number; color: string }; +export type PluginButtonIconProps = PluginHostProps & PluginButtonContext & PluginIconProps; export type PluginButtonContentProps = PluginHostProps & PluginButtonContext & { close(): void }; -export type PluginButtonIcon = string | ComponentType; +export type PluginButtonIcon = PluginIcon; export type PluginButtonBehavior = | { kind: "action"; onPress(): void | Promise } diff --git a/packages/plugin/src/client/contracts.ts b/packages/plugin/src/client/contracts.ts index 5bc82d8a58..28790e77bb 100644 --- a/packages/plugin/src/client/contracts.ts +++ b/packages/plugin/src/client/contracts.ts @@ -17,6 +17,7 @@ import type { PluginTimelineTransformResult, PluginCleanup, } from "../contracts.js"; +import type { PluginIconProps, PluginSerializableIcon } from "../icons.js"; export interface PluginHostProps { theme: PluginTheme; @@ -87,11 +88,13 @@ export interface PluginSidebarItemContribution { Component: ComponentType; } -export interface PluginIconProps { - name: string; - size?: number; - color?: string; -} +/** + * A Lucide icon name, inline SVG markup, or a component. Components receive the surface's size + * and color; buttons widen the props with their host and target context. + */ +export type PluginIcon = + | PluginSerializableIcon + | ComponentType; export type PluginPanelLocation = "workspace" | "explorer"; @@ -102,7 +105,7 @@ export interface PluginOpenPanelOptions { interface PluginWorkspacePanelBase { id: string; title: string; - icon: string; + icon: PluginIcon; locations?: readonly PluginPanelLocation[]; } @@ -168,7 +171,7 @@ export type PluginWorkspacePanelContribution = export interface PluginSettingsScreenContribution { id: string; title: string; - icon: string; + icon: PluginIcon; Component: ComponentType; } @@ -190,7 +193,7 @@ export interface PluginSurfaceContribution { export interface PluginSidebarContribution { id: string; title: string; - icon: string; + icon: PluginIcon; surface: string; } @@ -259,7 +262,7 @@ export interface PluginAgentCommandContext extends PluginCommandCapabilities { interface PluginCommandCenterItemBase { id: string; title: string; - icon: string; + icon: PluginIcon; keywords?: readonly string[]; } diff --git a/packages/plugin/src/client/index.ts b/packages/plugin/src/client/index.ts index 810462354f..93d57d0cc1 100644 --- a/packages/plugin/src/client/index.ts +++ b/packages/plugin/src/client/index.ts @@ -8,7 +8,7 @@ export type { PluginScreenLocation, PluginSidebarItemProps, PluginSidebarItemContribution, - PluginIconProps, + PluginIcon, PluginPanelLocation, PluginOpenPanelOptions, PluginWorkspacePanelProps, @@ -45,6 +45,7 @@ export type { PluginComposerPillContribution, PluginHeaderButtonContribution, } from "./buttons.js"; +export type { PluginIconProps, PluginSerializableIcon, PluginSvgIcon } from "../icons.js"; export { usePaseo } from "./paseo-context.js"; export { useAgent, useWorkspace } from "./client-state.js"; export { useRpc } from "./rpc-context.js"; diff --git a/packages/plugin/src/client/react-native.ts b/packages/plugin/src/client/react-native.ts index ea196c433f..f5862b31d1 100644 --- a/packages/plugin/src/client/react-native.ts +++ b/packages/plugin/src/client/react-native.ts @@ -17,7 +17,8 @@ import type { TextInput as NativeTextInput, TextInputProps, } from "react-native"; -import type { PluginIconProps } from "./contracts.js"; +import type { PluginIconProps } from "../icons.js"; +import type { PluginIcon } from "./contracts.js"; export interface ModalProps { title: string; @@ -53,12 +54,16 @@ export interface ToastApi { error(message: string): void; } -export declare const Icon: ComponentType; +/** Renders a Lucide icon by `name`, or any plugin icon by `icon`. An unusable icon renders nothing. */ +export type IconProps = Partial & + ({ name: string; icon?: never } | { icon: PluginIcon; name?: never }); + +export declare const Icon: ComponentType; export declare const Modal: ModalComponent; export declare function useToast(): ToastApi; export declare function useRevealedText(text: string, phase: "streaming" | "complete"): string; -export type { PluginIconProps } from "./contracts.js"; +export type { PluginIconProps } from "../icons.js"; /** React Native scrolling with the host's sheet gestures when rendered inside a sheet. */ export declare const ScrollView: ForwardRefExoticComponent< diff --git a/packages/plugin/src/client/ui.ts b/packages/plugin/src/client/ui.ts index 6686d8292b..8d5e3ff686 100644 --- a/packages/plugin/src/client/ui.ts +++ b/packages/plugin/src/client/ui.ts @@ -1,4 +1,5 @@ import type { ComponentType, ReactNode, Ref } from "react"; +import type { PluginIcon } from "./contracts.js"; export interface SettingsSectionProps { title: string; @@ -64,14 +65,14 @@ export interface ExternalLinkProps { } export declare const ExternalLink: ComponentType; -export type SidebarIcon = string | ComponentType<{ size: number; color: string }>; +export type SidebarIcon = PluginIcon; export interface SidebarRowProps { /** * Tells rows of one item apart when the item renders several: "bot-2". Unique within the item. * Omit it when the item renders one row. */ id?: string; - /** A Lucide icon name or a component. */ + /** A Lucide icon name, inline SVG, or a component. */ icon?: SidebarIcon; /** Defaults to the item's registered title. */ label?: string; diff --git a/packages/plugin/src/contracts.ts b/packages/plugin/src/contracts.ts index 98df0758a6..6694f05aea 100644 --- a/packages/plugin/src/contracts.ts +++ b/packages/plugin/src/contracts.ts @@ -1,4 +1,5 @@ import type { JsonValue } from "@getpaseo/protocol/agent-types"; +import type { PluginSerializableIcon } from "./icons.js"; import type { PluginRpcContract } from "./rpc.js"; export interface PluginTheme { @@ -73,7 +74,7 @@ export interface PluginThemeContribution { export interface PluginAttachmentSourceContribution { id: string; title: string; - icon: string; + icon: PluginSerializableIcon; pickerTitle: string; searchPlaceholder: string; search: PluginRpcContract; diff --git a/packages/plugin/src/icons.test.ts b/packages/plugin/src/icons.test.ts new file mode 100644 index 0000000000..fd8ddbc9fb --- /dev/null +++ b/packages/plugin/src/icons.test.ts @@ -0,0 +1,53 @@ +import { describe, expect, it } from "vitest"; +import { findSvgIconProblem } from "./icons.js"; + +describe("findSvgIconProblem", () => { + it.each([ + ["a plain SVG", ''], + ["leading whitespace", '\n '], + [ + "a fragment reference", + '', + ], + ["currentColor fills", ''], + ])("accepts %s", (_name, svg) => { + expect(findSvgIconProblem(svg)).toBeNull(); + }); + + it.each([ + ["a non-SVG document", "hello", "not an SVG document"], + ["an element", "", "not an SVG document"], + ["a script", "", "script elements are not allowed"], + ["a foreign object", "", "foreignObject elements are not allowed"], + ["a style", "", "style elements are not allowed"], + [ + "an event handler", + '', + "event-handler attributes are not allowed", + ], + [ + "a javascript URL", + '', + "javascript URLs are not allowed", + ], + [ + "an external href", + '', + "external href references are not allowed", + ], + [ + "an external xlink:href", + "", + "external href references are not allowed", + ], + ["markup over 64 KiB", `${" ".repeat(64 * 1024)}`, "exceeds 64 KiB"], + ])("rejects %s", (_name, svg, reason) => { + expect(findSvgIconProblem(svg)).toBe(reason); + }); + + it("measures the size in UTF-8 bytes", () => { + const multibyte = "é".repeat(32 * 1024); + + expect(findSvgIconProblem(`${multibyte}`)).toBe("exceeds 64 KiB"); + }); +}); diff --git a/packages/plugin/src/icons.ts b/packages/plugin/src/icons.ts new file mode 100644 index 0000000000..558aa2497d --- /dev/null +++ b/packages/plugin/src/icons.ts @@ -0,0 +1,38 @@ +/** What a component icon receives from the surface that draws it. */ +export interface PluginIconProps { + size: number; + color: string; +} + +/** Inline SVG markup. Paseo validates it when the contribution registers. */ +export interface PluginSvgIcon { + svg: string; +} + +/** An icon that can be stored or sent: a Lucide icon name, or inline SVG. */ +export type PluginSerializableIcon = string | PluginSvgIcon; + +export const PLUGIN_SVG_ICON_MAX_BYTES = 64 * 1024; + +const EXTERNAL_HREF = /\s(?:href|xlink:href)\s*=\s*(?:(["'])(.*?)\1|([^\s>]+))/gi; + +/** + * Why Paseo refuses to render this SVG, or null when it is a self-contained document. + * The daemon applies it to provider and usage-source icon files; the app to inline plugin icons. + */ +export function findSvgIconProblem(svg: string): string | null { + if (new TextEncoder().encode(svg).byteLength > PLUGIN_SVG_ICON_MAX_BYTES) { + return "exceeds 64 KiB"; + } + if (!/^\s*)/i.test(svg)) return "not an SVG document"; + if (/)/i.test(svg)) return "script elements are not allowed"; + if (/)/i.test(svg)) return "foreignObject elements are not allowed"; + if (/)/i.test(svg)) return "style elements are not allowed"; + if (/\son[a-z0-9_-]*\s*=/i.test(svg)) return "event-handler attributes are not allowed"; + if (/javascript\s*:/i.test(svg)) return "javascript URLs are not allowed"; + for (const match of svg.matchAll(EXTERNAL_HREF)) { + const href = match[2] ?? match[3] ?? ""; + if (!href.startsWith("#")) return "external href references are not allowed"; + } + return null; +} diff --git a/packages/plugin/src/index.ts b/packages/plugin/src/index.ts index 48deede303..29f5e72089 100644 --- a/packages/plugin/src/index.ts +++ b/packages/plugin/src/index.ts @@ -20,3 +20,10 @@ export { type PluginAttachmentSearchPayload, } from "./attachments.js"; export { defineRpc, type PluginRpcContract, type RpcInput, type RpcOutput } from "./rpc.js"; +export { + findSvgIconProblem, + PLUGIN_SVG_ICON_MAX_BYTES, + type PluginIconProps, + type PluginSerializableIcon, + type PluginSvgIcon, +} from "./icons.js"; diff --git a/packages/protocol/package.json b/packages/protocol/package.json index 964ff5a51e..770ae5f50f 100644 --- a/packages/protocol/package.json +++ b/packages/protocol/package.json @@ -1,6 +1,6 @@ { "name": "@getpaseo/protocol", - "version": "0.12.0-beta.1", + "version": "0.12.0", "description": "Paseo shared protocol schemas and wire types", "files": [ "dist", diff --git a/packages/protocol/src/agent-message-display.ts b/packages/protocol/src/agent-message-display.ts deleted file mode 100644 index c95f9e8206..0000000000 --- a/packages/protocol/src/agent-message-display.ts +++ /dev/null @@ -1,25 +0,0 @@ -import type { AgentMessage } from "./agent-message.js"; -import type { ToolCallDetail } from "./agent-types.js"; - -/** Presentation shared by clients; never used to encode provider prompts. */ -export function buildAgentMessageDisplay(message: AgentMessage): { - displayName: string; - detail: ToolCallDetail; -} { - const sender = message.sender.title ?? message.sender.id; - const headings: Record = { - message: `Message from ${sender}`, - finished: `${sender} finished`, - errored: `${sender} errored`, - "permission-required": `${sender} needs permission`, - closed: `${sender} closed`, - }; - return { - displayName: headings[message.event], - detail: { - type: "plain_text", - icon: "bot", - text: `From agent: ${message.sender.id}\n\n${message.text}`, - }, - }; -} diff --git a/packages/protocol/src/client-capabilities.ts b/packages/protocol/src/client-capabilities.ts index 0947b81027..a35852cc06 100644 --- a/packages/protocol/src/client-capabilities.ts +++ b/packages/protocol/src/client-capabilities.ts @@ -43,6 +43,7 @@ export const CLIENT_CAPS = { timelineNotifications: "timeline_notifications", // COMPAT(pluginTimelineItems): added in v0.8.0, remove after 2027-03-07 once client floor >= v0.8.0. pluginTimelineItems: "plugin_timeline_items", + workspaceSetupObservation: "workspace_setup_observation", // COMPAT(workspaceSetupBlocked): added in v0.8.0, remove after 2027-03-07 once client floor >= v0.8.0. workspaceSetupBlocked: "workspace_setup_blocked", browserHost: "browser_host", diff --git a/packages/protocol/src/messages.ts b/packages/protocol/src/messages.ts index c8fe60ff67..f7c43f224a 100644 --- a/packages/protocol/src/messages.ts +++ b/packages/protocol/src/messages.ts @@ -2556,6 +2556,12 @@ export const WorkspaceSetupStatusRequestSchema = z.object({ requestId: z.string(), }); +export const WorkspaceSetupSubscribeRequestSchema = z.object({ + type: z.literal("workspace.setup.subscribe.request"), + workspaceId: z.string(), + requestId: z.string(), +}); + export const WorkspaceSetupRunRequestSchema = z.object({ type: z.literal("workspace.setup.run.request"), workspaceId: z.string(), @@ -3335,6 +3341,7 @@ export const SessionInboundMessageSchema = z.discriminatedUnion("type", [ PaseoWorktreeArchiveRequestSchema, CreatePaseoWorktreeRequestSchema, WorkspaceSetupStatusRequestSchema, + WorkspaceSetupSubscribeRequestSchema, WorkspaceSetupRunRequestSchema, LegacyListAvailableEditorsRequestSchema, LegacyOpenInEditorRequestSchema, @@ -3725,6 +3732,7 @@ export const ServerInfoStatusPayloadSchema = z selectiveAgentTimeline: z.boolean().optional(), explicitEventSubscriptions: z.boolean().optional(), ownedSubscriptions: z.boolean().optional(), + workspaceSetupObservation: z.boolean().optional(), // COMPAT(canonicalSubmittedPrompts): added in v0.2.6, remove gate after 2027-01-30. canonicalSubmittedPrompts: z.boolean().optional(), agentMessageProvenance: z.boolean().optional(), @@ -4035,6 +4043,8 @@ export const WorkspaceDescriptorPayloadSchema = z projectCustomIconRevision: z.string().nullable().optional(), projectRootPath: z.string(), workspaceDirectory: z.string().optional(), + // COMPAT(workspaceSetupObservation): added in v0.12.0, remove optional after 2027-04-19. + setupStatus: z.enum(["running", "completed", "failed", "blocked"]).nullable().optional(), // COMPAT(worktreeSlug): added in v0.2.6, remove optional after 2027-01-31. // Present only for Paseo-owned worktrees; this is the basename of their root directory. worktreeSlug: z.string().optional(), @@ -4422,6 +4432,16 @@ export const WorkspaceSetupSnapshotSchema = z.object({ .optional(), }); +export const WorkspaceSetupSubscribeResponseSchema = z.object({ + type: z.literal("workspace.setup.subscribe.response"), + payload: z.object({ + requestId: z.string(), + subscriptionId: z.string().optional(), + workspaceId: z.string(), + snapshot: WorkspaceSetupSnapshotSchema.nullable(), + }), +}); + export const WorkspaceSetupRunResponseMessageSchema = z.object({ type: z.literal("workspace.setup.run.response"), payload: z.object({ @@ -6306,14 +6326,15 @@ export const UsageProblemSchema = z.discriminatedUnion("kind", [ }), z.object({ kind: z.literal("no_quota"), detail: z.string() }), ]); +const AvailableUsageReportSchema = z.object({ + status: z.literal("available"), + planLabel: z.string().optional(), + windows: z.array(ProviderUsageWindowSchema), + balances: z.array(ProviderUsageBalanceSchema).optional(), + details: z.array(ProviderUsageDetailSchema).optional(), +}); export const UsageReportSchema = z.discriminatedUnion("status", [ - z.object({ - status: z.literal("available"), - planLabel: z.string().optional(), - windows: z.array(ProviderUsageWindowSchema), - balances: z.array(ProviderUsageBalanceSchema).optional(), - details: z.array(ProviderUsageDetailSchema).optional(), - }), + AvailableUsageReportSchema, z.object({ status: z.literal("unavailable"), problem: UsageProblemSchema }), z.object({ status: z.literal("error"), error: z.string() }), ]); @@ -6325,6 +6346,11 @@ export const UsageReportEntrySchema = z.object({ sourceLabel: z.string(), icon: z.string().optional(), report: UsageReportSchema, + // Successful completion time; fetchedAt remains the attempt timestamp for ordering. + successfulAt: z.string().optional(), + lastSuccessful: z + .object({ fetchedAt: z.string(), report: AvailableUsageReportSchema }) + .optional(), loginErrors: z .array( z.object({ @@ -6903,6 +6929,7 @@ export const SessionOutboundMessageSchema = z.discriminatedUnion("type", [ ScriptStatusUpdateMessageSchema, WorkspaceSetupProgressMessageSchema, WorkspaceSetupStatusResponseMessageSchema, + WorkspaceSetupSubscribeResponseSchema, WorkspaceSetupRunResponseMessageSchema, AgentStreamMessageSchema, AgentStatusMessageSchema, diff --git a/packages/protocol/src/messages.wire-compat.test.ts b/packages/protocol/src/messages.wire-compat.test.ts index 2298d680a4..6903aa2cd1 100644 --- a/packages/protocol/src/messages.wire-compat.test.ts +++ b/packages/protocol/src/messages.wire-compat.test.ts @@ -1,6 +1,7 @@ import { describe, expect, test } from "vitest"; import { z } from "zod"; import { + UsageReportEntrySchema, AgentSnapshotPayloadSchema, AgentTimelineItemPayloadSchema, ServerInfoStatusPayloadSchema, @@ -436,3 +437,40 @@ test("usage login errors are additive and older reports still parse", () => { expect(SessionOutboundMessageSchema.parse(newMessage)).toEqual(newMessage); expect(legacy.parse(newMessage)).toEqual(oldMessage); }); + +test("usage entries accept older failures and additive successful snapshots", () => { + const oldEntry = { + id: "source:account", + sourceId: "source", + sourceLabel: "Source", + account: {}, + fetchedAt: "2026-10-17T10:06:00Z", + report: { status: "error", error: "Rate limited" }, + }; + expect(UsageReportEntrySchema.parse(oldEntry)).toEqual(oldEntry); + const retained = { + ...oldEntry, + lastSuccessful: { + fetchedAt: "2026-10-17T10:00:00Z", + report: { status: "available", windows: [{ id: "weekly", label: "Weekly", usedPct: 42 }] }, + }, + }; + expect(UsageReportEntrySchema.parse(retained)).toEqual(retained); + const available = { + ...oldEntry, + report: retained.lastSuccessful.report, + successfulAt: "2026-10-17T10:00:15Z", + }; + expect(UsageReportEntrySchema.parse(available)).toEqual(available); + expect( + UsageReportEntrySchema.omit({ lastSuccessful: true, successfulAt: true }).parse(available), + ).toEqual({ ...oldEntry, report: available.report }); + // An older client's entry shape strips the additive snapshot and still sees the failure. + expect(UsageReportEntrySchema.omit({ lastSuccessful: true }).parse(retained)).toEqual(oldEntry); + expect( + UsageReportEntrySchema.safeParse({ + ...oldEntry, + lastSuccessful: { fetchedAt: oldEntry.fetchedAt, report: oldEntry.report }, + }).success, + ).toBe(false); +}); diff --git a/packages/protocol/src/paseo-tool-call-detail.ts b/packages/protocol/src/paseo-tool-call-detail.ts index 4b06d49923..2fd856cee3 100644 --- a/packages/protocol/src/paseo-tool-call-detail.ts +++ b/packages/protocol/src/paseo-tool-call-detail.ts @@ -1,357 +1,6 @@ -import { getPaseoToolLeafName } from "./tool-name-normalization.js"; - -export interface PaseoToolDetailField { - label: string; - value: string; -} - -export type PaseoToolDetailSection = - | { - kind: "prose"; - title: string; - text: string; - } - | { - kind: "fields"; - title: string; - fields: PaseoToolDetailField[]; - }; - -interface ToolDetailSpec { - promptField?: string; - inputOrder?: readonly string[]; - outputFields?: readonly string[]; -} - -const WORKSPACE_FIELDS = [ - "title", - "workspaceId", - "projectId", - "isolation", - "path", - "mode", - "worktreeSlug", - "branchName", - "baseBranch", - "branch", - "prNumber", - "forge", -] as const; -const AGENT_FIELDS = [ - "title", - "agentId", - "provider", - "workspaceId", - "cwd", - "sessionMode", - "modeId", - "background", - "notifyOnFinish", - "internal", - "settings", - "labels", -] as const; -const AUTOMATION_FIELDS = [ - "name", - "id", - "cron", - "timezone", - "provider", - "cwd", - "isolation", - "maxRuns", - "expiresIn", - "clearExpires", -] as const; -const BROWSER_FIELDS = [ - "browserId", - "url", - "ref", - "sourceRef", - "targetRef", - "value", - "text", - "key", - "button", - "doubleClick", - "modifiers", - "filePaths", - "fullPage", - "maxEntries", - "timeoutMs", - "deltaX", - "deltaY", - "width", - "height", - "function", -] as const; - -const TOOL_SPECS: Readonly> = { - create_workspace: { - inputOrder: WORKSPACE_FIELDS, - outputFields: ["workspaceId", "projectId"], - }, - list_workspaces: {}, - archive_workspace: { - inputOrder: ["workspaceId"], - outputFields: ["workspaceId", "archivedAgentIds", "removedDirectory"], - }, - rename_workspace: { inputOrder: ["title", "workspaceId"] }, - create_agent: { - promptField: "initialPrompt", - inputOrder: AGENT_FIELDS, - outputFields: ["agentId", "status", "currentModeId", "cwd"], - }, - send_agent_prompt: { - promptField: "prompt", - inputOrder: AGENT_FIELDS, - outputFields: ["status", "lastMessage", "permission"], - }, - get_agent_status: { inputOrder: ["agentId"] }, - list_agents: { inputOrder: ["cwd", "statuses", "sinceHours", "limit", "includeArchived"] }, - cancel_agent: { inputOrder: ["agentId"] }, - archive_agent: { inputOrder: ["agentId"] }, - kill_agent: { inputOrder: ["agentId"] }, - update_agent: { inputOrder: AGENT_FIELDS }, - get_agent_activity: { inputOrder: ["agentId", "limit"] }, - set_agent_mode: { inputOrder: ["agentId", "modeId"] }, - list_workspace_scripts: { inputOrder: ["workspaceId"] }, - start_workspace_script: { inputOrder: ["workspaceId", "scriptName"] }, - stop_workspace_script: { inputOrder: ["workspaceId", "scriptName"] }, - list_terminals: { inputOrder: ["cwd", "all"] }, - create_terminal: { inputOrder: ["cwd", "workspaceId", "name", "command"] }, - kill_terminal: { inputOrder: ["terminalId"] }, - capture_terminal: { inputOrder: ["terminalId", "lines"] }, - send_terminal_keys: { inputOrder: ["terminalId", "keys", "literal"] }, - create_schedule: { - promptField: "prompt", - inputOrder: AUTOMATION_FIELDS, - outputFields: ["id", "status", "nextRunAt", "expiresAt"], - }, - create_heartbeat: { - promptField: "prompt", - inputOrder: AUTOMATION_FIELDS, - outputFields: ["id", "status", "nextRunAt", "expiresAt"], - }, - delete_heartbeat: { inputOrder: ["id"] }, - list_schedules: {}, - inspect_schedule: { inputOrder: ["id"] }, - pause_schedule: { inputOrder: ["id"] }, - resume_schedule: { inputOrder: ["id"] }, - delete_schedule: { inputOrder: ["id"] }, - update_schedule: { promptField: "prompt", inputOrder: AUTOMATION_FIELDS }, - schedule_logs: { inputOrder: ["id"] }, - run_schedule_once: { inputOrder: ["id"] }, - list_providers: {}, - list_models: { inputOrder: ["provider"] }, - list_profiles: {}, - inspect_provider: { inputOrder: ["provider", "cwd", "settings"] }, - list_pending_permissions: {}, - respond_to_permission: { inputOrder: ["agentId", "requestId", "response"] }, - browser_list_tabs: {}, - browser_new_tab: { inputOrder: BROWSER_FIELDS }, - browser_snapshot: { inputOrder: BROWSER_FIELDS }, - browser_click: { inputOrder: BROWSER_FIELDS }, - browser_fill: { inputOrder: BROWSER_FIELDS }, - browser_wait: { inputOrder: BROWSER_FIELDS }, - browser_type: { inputOrder: BROWSER_FIELDS }, - browser_keypress: { inputOrder: BROWSER_FIELDS }, - browser_navigate: { inputOrder: BROWSER_FIELDS }, - browser_back: { inputOrder: BROWSER_FIELDS }, - browser_forward: { inputOrder: BROWSER_FIELDS }, - browser_reload: { inputOrder: BROWSER_FIELDS }, - browser_screenshot: { inputOrder: BROWSER_FIELDS }, - browser_upload: { inputOrder: BROWSER_FIELDS }, - browser_hover: { inputOrder: BROWSER_FIELDS }, - browser_select: { inputOrder: BROWSER_FIELDS }, - browser_drag: { inputOrder: BROWSER_FIELDS }, - browser_logs: { inputOrder: BROWSER_FIELDS }, - browser_evaluate: { inputOrder: BROWSER_FIELDS }, - browser_scroll: { inputOrder: BROWSER_FIELDS }, - browser_resize: { inputOrder: BROWSER_FIELDS }, - browser_close_tab: { inputOrder: BROWSER_FIELDS }, -}; - -const FIELD_LABELS: Readonly> = { - agentId: "Agent", - archivedAgentIds: "Archived agents", - baseBranch: "Base branch", - branchName: "New branch", - browserId: "Browser tab", - clearExpires: "Clear expiry", - currentModeId: "Current mode", - cwd: "Working directory", - deltaX: "Horizontal delta", - deltaY: "Vertical delta", - doubleClick: "Double click", - expiresIn: "Expires in", - expiresAt: "Expires", - filePaths: "Files", - fullPage: "Full page", - initialPrompt: "Prompt", - id: "ID", - lastMessage: "Last message", - maxEntries: "Maximum entries", - maxRuns: "Maximum runs", - modeId: "Mode", - newMode: "New mode", - nextRunAt: "Next run", - notifyOnFinish: "Notify on finish", - internal: "Internal", - prNumber: "Change request", - projectId: "Project", - removedDirectory: "Removed directory", - requestId: "Request", - scriptName: "Script", - sessionMode: "Session mode", - sinceHours: "Since (hours)", - sourceRef: "Source", - targetRef: "Target", - terminalId: "Terminal", - thinkingOptionId: "Thinking", - timeoutMs: "Timeout (ms)", - updateCount: "Updates", - workspaceId: "Workspace", - worktreeSlug: "Worktree", -}; - -function isRecord(value: unknown): value is Record { - return typeof value === "object" && value !== null && !Array.isArray(value); -} - -function humanizeKey(key: string): string { - const known = FIELD_LABELS[key]; - if (known) return known; - const words = key - .replace(/([a-z0-9])([A-Z])/g, "$1 $2") - .replace(/[._-]+/g, " ") - .split(" ") - .filter(Boolean); - const sentence = words.join(" ").toLowerCase(); - return `${sentence[0]?.toUpperCase() ?? ""}${sentence.slice(1)}`; -} - -function formatValue(value: unknown, depth = 0): string { - if (value === null) return "None"; - if (value === undefined) return ""; - if (typeof value === "boolean") return value ? "Yes" : "No"; - if (typeof value === "string" || typeof value === "number" || typeof value === "bigint") { - return String(value); - } - if (Array.isArray(value)) { - if (value.length === 0) return "None"; - return value.map((item) => `• ${indentMultiline(formatValue(item, depth + 1), 2)}`).join("\n"); - } - if (isRecord(value)) { - const entries = Object.entries(value).filter(([, child]) => child !== undefined); - if (entries.length === 0) return "None"; - return entries - .map(([key, child]) => { - const formatted = formatValue(child, depth + 1); - return `${humanizeKey(key)}: ${indentMultiline(formatted, 2)}`; - }) - .join("\n"); - } - return String(value); -} - -function indentMultiline(value: string, spaces: number): string { - const indentation = " ".repeat(spaces); - return value.replace(/\n/g, `\n${indentation}`); -} - -function orderedEntries( - value: Record, - order: readonly string[] = [], - omittedKey?: string, - includedKeys?: readonly string[], -): Array<[string, unknown]> { - const included = includedKeys ? new Set(includedKeys) : null; - const keys = Object.keys(value).filter( - (key) => key !== omittedKey && value[key] !== undefined && (!included || included.has(key)), - ); - const rank = new Map(order.map((key, index) => [key, index])); - keys.sort((left, right) => { - const leftRank = rank.get(left) ?? Number.MAX_SAFE_INTEGER; - const rightRank = rank.get(right) ?? Number.MAX_SAFE_INTEGER; - return leftRank - rightRank || left.localeCompare(right); - }); - return keys.map((key) => [key, value[key]]); -} - -function fieldsFromValue( - value: unknown, - order?: readonly string[], - omittedKey?: string, - includedKeys?: readonly string[], -): PaseoToolDetailField[] { - if (value === null || value === undefined) return []; - if (!isRecord(value)) { - const formatted = formatValue(value); - return formatted ? [{ label: "Value", value: formatted }] : []; - } - return orderedEntries(value, order, omittedKey, includedKeys).map(([key, child]) => ({ - label: humanizeKey(key), - value: formatValue(child), - })); -} - -function parseJsonText(value: unknown): unknown { - if (typeof value !== "string") return undefined; - try { - return JSON.parse(value) as unknown; - } catch { - return undefined; - } -} - -function unwrapMcpResult(output: unknown): unknown { - if (!isRecord(output)) return output; - - if (output.structuredContent !== undefined) { - return output.structuredContent; - } - - if (Array.isArray(output.content) && output.content.length === 1) { - const item = output.content[0]; - if (isRecord(item) && item.type === "text") { - return parseJsonText(item.text) ?? item.text; - } - } - - return output; -} - -export function buildPaseoToolDetailSections( - toolName: string, - input: unknown, - output: unknown, -): PaseoToolDetailSection[] | null { - const leafName = getPaseoToolLeafName(toolName); - if (!leafName) return null; - - const spec = TOOL_SPECS[leafName] ?? {}; - const sections: PaseoToolDetailSection[] = []; - if (spec.promptField && isRecord(input)) { - const prompt = input[spec.promptField]; - if (typeof prompt === "string" && prompt.length > 0) { - sections.push({ kind: "prose", title: "Prompt", text: prompt }); - } - } - - const inputFields = fieldsFromValue(input, spec.inputOrder, spec.promptField); - if (inputFields.length > 0) { - sections.push({ kind: "fields", title: "Details", fields: inputFields }); - } - - const outputFields = fieldsFromValue( - unwrapMcpResult(output), - spec.outputFields, - undefined, - spec.outputFields, - ); - if (outputFields.length > 0) { - sections.push({ kind: "fields", title: "Result", fields: outputFields }); - } - return sections; -} +// COMPAT(paseoToolCallDetail): added in v0.12.0, remove after 2027-04-19 once plugins have migrated to paseo-tool-presentation/index. +export { + buildPaseoToolDetailSections, + type PaseoToolDetailField, + type PaseoToolDetailSection, +} from "./paseo-tool-presentation/index.js"; diff --git a/packages/protocol/src/paseo-tool-presentation/agent-message.ts b/packages/protocol/src/paseo-tool-presentation/agent-message.ts new file mode 100644 index 0000000000..33eb44163b --- /dev/null +++ b/packages/protocol/src/paseo-tool-presentation/agent-message.ts @@ -0,0 +1,31 @@ +import type { AgentMessage } from "../agent-message.js"; +import type { ToolCallDetail } from "../agent-types.js"; +import { toSummaryText } from "./summary-text.js"; + +export interface AgentMessageDisplay { + displayName: string; + summary?: string; + detail: ToolCallDetail; +} + +/** Events read noun-first ("Agent finished"); the sender goes in the summary. */ +const EVENT_LABELS: Record = { + message: "Message received", + finished: "Agent finished", + errored: "Agent errored", + "permission-required": "Agent needs permission", + closed: "Agent closed", +}; + +/** Presentation shared by clients; never used to encode provider prompts. */ +export function buildAgentMessageDisplay(message: AgentMessage): AgentMessageDisplay { + const summary = toSummaryText(message.sender.title ?? message.sender.id); + return { + displayName: EVENT_LABELS[message.event], + ...(summary ? { summary } : {}), + detail: { + type: "plain_text", + text: `From agent: ${message.sender.id}\n\n${message.text}`, + }, + }; +} diff --git a/packages/protocol/src/paseo-tool-presentation/catalog.ts b/packages/protocol/src/paseo-tool-presentation/catalog.ts new file mode 100644 index 0000000000..1706134523 --- /dev/null +++ b/packages/protocol/src/paseo-tool-presentation/catalog.ts @@ -0,0 +1,349 @@ +/** + * One entry per Paseo MCP tool: the timeline label, the context shown after it, + * and how the expanded details lay out the call. + * + * Labels are fixed text so truncation never hides them. Actions read verb-first + * ("Send message"); the context goes in the summary. + */ + +type ToolInput = Readonly>; + +/** `targetAgent` is the target agent's title when known, else its ID. */ +export type PaseoToolContext = (input: ToolInput, targetAgent: string | undefined) => unknown; + +export interface PaseoToolDetailSpec { + promptField?: string; + inputOrder?: readonly string[]; + outputFields?: readonly string[]; +} + +export interface PaseoToolEntry { + label: string; + context?: PaseoToolContext; + detail?: PaseoToolDetailSpec; +} + +const WORKSPACE_FIELDS = [ + "title", + "workspaceId", + "projectId", + "isolation", + "path", + "mode", + "worktreeSlug", + "branchName", + "baseBranch", + "branch", + "prNumber", + "forge", +] as const; +const AGENT_FIELDS = [ + "title", + "agentId", + "provider", + "workspaceId", + "cwd", + "sessionMode", + "modeId", + "background", + "notifyOnFinish", + "internal", + "settings", + "labels", +] as const; +const AUTOMATION_FIELDS = [ + "name", + "id", + "cron", + "timezone", + "provider", + "cwd", + "isolation", + "maxRuns", + "expiresIn", + "clearExpires", +] as const; +const BROWSER_FIELDS = [ + "browserId", + "url", + "ref", + "sourceRef", + "targetRef", + "value", + "text", + "key", + "button", + "doubleClick", + "modifiers", + "filePaths", + "fullPage", + "maxEntries", + "timeoutMs", + "deltaX", + "deltaY", + "width", + "height", + "function", +] as const; + +const AUTOMATION_OUTPUT = ["id", "status", "nextRunAt", "expiresAt"] as const; + +function field(...keys: string[]): PaseoToolContext { + return (input) => keys.map((key) => input[key]).find(isPresent); +} + +function targetAgent(): PaseoToolContext { + return (_input, agent) => agent; +} + +function fieldOrTargetAgent(key: string): PaseoToolContext { + return (input, agent) => (isPresent(input[key]) ? input[key] : agent); +} + +function workspaceContext(): PaseoToolContext { + return (input) => + [input.title, input.branchName, input.branch, baseName(input.path)].find(isPresent); +} + +function viewportContext(): PaseoToolContext { + return (input) => + typeof input.width === "number" && typeof input.height === "number" + ? `${input.width}×${input.height}` + : undefined; +} + +function isPresent(value: unknown): boolean { + if (typeof value === "string") return value.trim().length > 0; + if (Array.isArray(value)) return value.length > 0; + return typeof value === "number"; +} + +function baseName(value: unknown): string | undefined { + if (typeof value !== "string") return undefined; + return value.split(/[\\/]/).findLast((segment) => segment.length > 0); +} + +function browser(label: string, context?: PaseoToolContext): PaseoToolEntry { + return { label, ...(context ? { context } : {}), detail: { inputOrder: BROWSER_FIELDS } }; +} + +export const PASEO_TOOL_CATALOG = { + // Agents + create_agent: { + label: "Create agent", + context: field("title", "initialPrompt"), + detail: { + promptField: "initialPrompt", + inputOrder: AGENT_FIELDS, + outputFields: ["agentId", "status", "currentModeId", "cwd"], + }, + }, + send_agent_prompt: { + label: "Send message", + context: field("prompt"), + detail: { + promptField: "prompt", + inputOrder: AGENT_FIELDS, + outputFields: ["status", "lastMessage", "permission"], + }, + }, + get_agent_status: { + label: "Check agent", + context: targetAgent(), + detail: { inputOrder: ["agentId"] }, + }, + get_agent_activity: { + label: "Read agent activity", + context: targetAgent(), + detail: { inputOrder: ["agentId", "limit"] }, + }, + list_agents: { + label: "List agents", + detail: { inputOrder: ["cwd", "statuses", "sinceHours", "limit", "includeArchived"] }, + }, + update_agent: { + label: "Update agent", + context: fieldOrTargetAgent("name"), + detail: { inputOrder: AGENT_FIELDS }, + }, + set_agent_mode: { + label: "Set agent mode", + context: field("modeId"), + detail: { inputOrder: ["agentId", "modeId"] }, + }, + cancel_agent: { + label: "Cancel agent", + context: targetAgent(), + detail: { inputOrder: ["agentId"] }, + }, + archive_agent: { + label: "Archive agent", + context: targetAgent(), + detail: { inputOrder: ["agentId"] }, + }, + kill_agent: { label: "Kill agent", context: targetAgent(), detail: { inputOrder: ["agentId"] } }, + list_pending_permissions: { label: "List permissions" }, + respond_to_permission: { + label: "Respond to permission", + context: targetAgent(), + detail: { inputOrder: ["agentId", "requestId", "response"] }, + }, + + // Workspaces and scripts + create_workspace: { + label: "Create workspace", + context: workspaceContext(), + detail: { inputOrder: WORKSPACE_FIELDS, outputFields: ["workspaceId", "projectId"] }, + }, + list_workspaces: { label: "List workspaces" }, + rename_workspace: { + label: "Rename workspace", + context: field("title"), + detail: { inputOrder: ["title", "workspaceId"] }, + }, + archive_workspace: { + label: "Archive workspace", + context: field("workspaceId"), + detail: { + inputOrder: ["workspaceId"], + outputFields: ["workspaceId", "archivedAgentIds", "removedDirectory"], + }, + }, + list_workspace_scripts: { label: "List scripts", detail: { inputOrder: ["workspaceId"] } }, + start_workspace_script: { + label: "Start script", + context: field("scriptName"), + detail: { inputOrder: ["workspaceId", "scriptName"] }, + }, + stop_workspace_script: { + label: "Stop script", + context: field("scriptName"), + detail: { inputOrder: ["workspaceId", "scriptName"] }, + }, + + // Terminals + create_terminal: { + label: "Create terminal", + context: field("name", "command"), + detail: { inputOrder: ["cwd", "workspaceId", "name", "command"] }, + }, + list_terminals: { label: "List terminals", detail: { inputOrder: ["cwd", "all"] } }, + capture_terminal: { + label: "Read terminal", + context: field("terminalId"), + detail: { inputOrder: ["terminalId", "lines"] }, + }, + send_terminal_keys: { + label: "Send keys", + context: field("keys"), + detail: { inputOrder: ["terminalId", "keys", "literal"] }, + }, + kill_terminal: { + label: "Kill terminal", + context: field("terminalId"), + detail: { inputOrder: ["terminalId"] }, + }, + + // Schedules and heartbeats + create_schedule: { + label: "Create schedule", + context: field("name", "cron"), + detail: { + promptField: "prompt", + inputOrder: AUTOMATION_FIELDS, + outputFields: AUTOMATION_OUTPUT, + }, + }, + create_heartbeat: { + label: "Create heartbeat", + context: field("name", "cron"), + detail: { + promptField: "prompt", + inputOrder: AUTOMATION_FIELDS, + outputFields: AUTOMATION_OUTPUT, + }, + }, + update_schedule: { + label: "Update schedule", + context: field("name", "id"), + detail: { promptField: "prompt", inputOrder: AUTOMATION_FIELDS }, + }, + list_schedules: { label: "List schedules" }, + inspect_schedule: { + label: "Inspect schedule", + context: field("id"), + detail: { inputOrder: ["id"] }, + }, + schedule_logs: { + label: "Read schedule logs", + context: field("id"), + detail: { inputOrder: ["id"] }, + }, + run_schedule_once: { + label: "Run schedule", + context: field("id"), + detail: { inputOrder: ["id"] }, + }, + pause_schedule: { label: "Pause schedule", context: field("id"), detail: { inputOrder: ["id"] } }, + resume_schedule: { + label: "Resume schedule", + context: field("id"), + detail: { inputOrder: ["id"] }, + }, + delete_schedule: { + label: "Delete schedule", + context: field("id"), + detail: { inputOrder: ["id"] }, + }, + delete_heartbeat: { + label: "Delete heartbeat", + context: field("id"), + detail: { inputOrder: ["id"] }, + }, + + // Providers + list_providers: { label: "List providers" }, + list_models: { + label: "List models", + context: field("provider"), + detail: { inputOrder: ["provider"] }, + }, + list_profiles: { label: "List profiles" }, + inspect_provider: { + label: "Inspect provider", + context: field("provider"), + detail: { inputOrder: ["provider", "cwd", "settings"] }, + }, + + // Browser + browser_list_tabs: browser("List browser tabs"), + browser_new_tab: browser("Open browser tab", field("url")), + browser_close_tab: browser("Close browser tab", field("browserId")), + browser_navigate: browser("Navigate", field("url")), + browser_back: browser("Go back"), + browser_forward: browser("Go forward"), + browser_reload: browser("Reload page"), + browser_snapshot: browser("Snapshot page"), + browser_screenshot: browser("Take screenshot"), + browser_click: browser("Click element", field("ref")), + browser_hover: browser("Hover element", field("ref")), + browser_drag: browser("Drag element", field("sourceRef")), + browser_fill: browser("Fill field", field("ref")), + browser_select: browser("Select option", field("value", "ref")), + browser_type: browser("Type text", field("text")), + browser_keypress: browser("Press key", field("key")), + browser_upload: browser("Upload files", field("filePaths")), + browser_wait: browser("Wait for page", field("text", "url")), + browser_scroll: browser("Scroll page"), + browser_resize: browser("Resize browser", viewportContext()), + browser_logs: browser("Read browser logs"), + browser_evaluate: browser("Run JavaScript", field("function")), +} satisfies Record; + +export type PaseoToolName = keyof typeof PASEO_TOOL_CATALOG; + +export function getPaseoToolEntry(leafName: string): PaseoToolEntry | undefined { + return Object.prototype.hasOwnProperty.call(PASEO_TOOL_CATALOG, leafName) + ? PASEO_TOOL_CATALOG[leafName as PaseoToolName] + : undefined; +} diff --git a/packages/protocol/src/paseo-tool-call-detail.test.ts b/packages/protocol/src/paseo-tool-presentation/detail-sections.test.ts similarity index 60% rename from packages/protocol/src/paseo-tool-call-detail.test.ts rename to packages/protocol/src/paseo-tool-presentation/detail-sections.test.ts index 25a637e45c..c99e46248e 100644 --- a/packages/protocol/src/paseo-tool-call-detail.test.ts +++ b/packages/protocol/src/paseo-tool-presentation/detail-sections.test.ts @@ -1,6 +1,11 @@ +import { execFileSync } from "node:child_process"; +import { copyFileSync, mkdtempSync, rmSync, symlinkSync, writeFileSync } from "node:fs"; +import { tmpdir } from "node:os"; +import path from "node:path"; +import { fileURLToPath } from "node:url"; import { describe, expect, it } from "vitest"; -import { buildPaseoToolDetailSections } from "./paseo-tool-call-detail.js"; +import { buildPaseoToolDetailSections } from "./index.js"; describe("Paseo tool-call detail presentation", () => { it.each(["mcp__paseo__create_agent", "paseo.create_agent", "paseo_remote.create_agent"])( @@ -147,3 +152,75 @@ describe("Paseo tool-call detail presentation", () => { expect(buildPaseoToolDetailSections("mcp__github__create_issue", {}, {})).toBeNull(); }); }); + +describe("published Paseo tool-call detail entry", () => { + it("preserves the 0.11.4 runtime export and types at the old subpath", () => { + const packageRoot = fileURLToPath(new URL("../../", import.meta.url)); + const compiler = fileURLToPath( + new URL("../../../../node_modules/typescript/bin/tsc", import.meta.url), + ); + const fixture = mkdtempSync(path.join(tmpdir(), "paseo-tool-call-detail-")); + try { + copyFileSync(path.join(packageRoot, "package.json"), path.join(fixture, "package.json")); + symlinkSync( + path.join(packageRoot, "../../node_modules"), + path.join(fixture, "node_modules"), + "junction", + ); + execFileSync( + process.execPath, + [ + compiler, + "-p", + path.join(packageRoot, "tsconfig.json"), + "--outDir", + path.join(fixture, "dist"), + "--incremental", + "false", + ], + { stdio: "pipe" }, + ); + writeFileSync( + path.join(fixture, "consumer.mts"), + ` +import { strict as assert } from "node:assert"; +import { + buildPaseoToolDetailSections, + type PaseoToolDetailField, + type PaseoToolDetailSection, +} from "@getpaseo/protocol/paseo-tool-call-detail"; +import { buildPaseoToolDetailSections as current } from "@getpaseo/protocol/paseo-tool-presentation/index"; +const field: PaseoToolDetailField = { label: "Agent", value: "agt_123" }; +const sections: PaseoToolDetailSection[] = [ + { kind: "prose", title: "Prompt", text: "Hello" }, + { kind: "fields", title: "Details", fields: [field] }, +]; +const build: (toolName: string, input: unknown, output: unknown) => PaseoToolDetailSection[] | null = buildPaseoToolDetailSections; +assert.equal(build, current); +assert.deepEqual(build("mcp__paseo__send_agent_prompt", { prompt: "Hello", agentId: "agt_123" }, undefined), sections); +`, + ); + execFileSync( + process.execPath, + [ + compiler, + path.join(fixture, "consumer.mts"), + "--module", + "NodeNext", + "--moduleResolution", + "NodeNext", + "--target", + "ES2020", + "--strict", + "--skipLibCheck", + ], + { stdio: "inherit" }, + ); + expect( + execFileSync(process.execPath, [path.join(fixture, "consumer.mjs")], { encoding: "utf8" }), + ).toBe(""); + } finally { + rmSync(fixture, { recursive: true, force: true }); + } + }, 30_000); +}); diff --git a/packages/protocol/src/paseo-tool-presentation/detail-sections.ts b/packages/protocol/src/paseo-tool-presentation/detail-sections.ts new file mode 100644 index 0000000000..e2fbcbe9b0 --- /dev/null +++ b/packages/protocol/src/paseo-tool-presentation/detail-sections.ts @@ -0,0 +1,203 @@ +import { getPaseoToolLeafName } from "../tool-name-normalization.js"; +import { getPaseoToolEntry, type PaseoToolDetailSpec } from "./catalog.js"; + +export interface PaseoToolDetailField { + label: string; + value: string; +} + +export type PaseoToolDetailSection = + | { + kind: "prose"; + title: string; + text: string; + } + | { + kind: "fields"; + title: string; + fields: PaseoToolDetailField[]; + }; + +const FIELD_LABELS: Readonly> = { + agentId: "Agent", + archivedAgentIds: "Archived agents", + baseBranch: "Base branch", + branchName: "New branch", + browserId: "Browser tab", + clearExpires: "Clear expiry", + currentModeId: "Current mode", + cwd: "Working directory", + deltaX: "Horizontal delta", + deltaY: "Vertical delta", + doubleClick: "Double click", + expiresIn: "Expires in", + expiresAt: "Expires", + filePaths: "Files", + fullPage: "Full page", + initialPrompt: "Prompt", + id: "ID", + lastMessage: "Last message", + maxEntries: "Maximum entries", + maxRuns: "Maximum runs", + modeId: "Mode", + newMode: "New mode", + nextRunAt: "Next run", + notifyOnFinish: "Notify on finish", + internal: "Internal", + prNumber: "Change request", + projectId: "Project", + removedDirectory: "Removed directory", + requestId: "Request", + scriptName: "Script", + sessionMode: "Session mode", + sinceHours: "Since (hours)", + sourceRef: "Source", + targetRef: "Target", + terminalId: "Terminal", + thinkingOptionId: "Thinking", + timeoutMs: "Timeout (ms)", + updateCount: "Updates", + workspaceId: "Workspace", + worktreeSlug: "Worktree", +}; + +function isRecord(value: unknown): value is Record { + return typeof value === "object" && value !== null && !Array.isArray(value); +} + +function humanizeKey(key: string): string { + const known = FIELD_LABELS[key]; + if (known) return known; + const words = key + .replace(/([a-z0-9])([A-Z])/g, "$1 $2") + .replace(/[._-]+/g, " ") + .split(" ") + .filter(Boolean); + const sentence = words.join(" ").toLowerCase(); + return `${sentence[0]?.toUpperCase() ?? ""}${sentence.slice(1)}`; +} + +function formatValue(value: unknown, depth = 0): string { + if (value === null) return "None"; + if (value === undefined) return ""; + if (typeof value === "boolean") return value ? "Yes" : "No"; + if (typeof value === "string" || typeof value === "number" || typeof value === "bigint") { + return String(value); + } + if (Array.isArray(value)) { + if (value.length === 0) return "None"; + return value.map((item) => `• ${indentMultiline(formatValue(item, depth + 1), 2)}`).join("\n"); + } + if (isRecord(value)) { + const entries = Object.entries(value).filter(([, child]) => child !== undefined); + if (entries.length === 0) return "None"; + return entries + .map(([key, child]) => { + const formatted = formatValue(child, depth + 1); + return `${humanizeKey(key)}: ${indentMultiline(formatted, 2)}`; + }) + .join("\n"); + } + return String(value); +} + +function indentMultiline(value: string, spaces: number): string { + const indentation = " ".repeat(spaces); + return value.replace(/\n/g, `\n${indentation}`); +} + +function orderedEntries( + value: Record, + order: readonly string[] = [], + omittedKey?: string, + includedKeys?: readonly string[], +): Array<[string, unknown]> { + const included = includedKeys ? new Set(includedKeys) : null; + const keys = Object.keys(value).filter( + (key) => key !== omittedKey && value[key] !== undefined && (!included || included.has(key)), + ); + const rank = new Map(order.map((key, index) => [key, index])); + keys.sort((left, right) => { + const leftRank = rank.get(left) ?? Number.MAX_SAFE_INTEGER; + const rightRank = rank.get(right) ?? Number.MAX_SAFE_INTEGER; + return leftRank - rightRank || left.localeCompare(right); + }); + return keys.map((key) => [key, value[key]]); +} + +function fieldsFromValue( + value: unknown, + order?: readonly string[], + omittedKey?: string, + includedKeys?: readonly string[], +): PaseoToolDetailField[] { + if (value === null || value === undefined) return []; + if (!isRecord(value)) { + const formatted = formatValue(value); + return formatted ? [{ label: "Value", value: formatted }] : []; + } + return orderedEntries(value, order, omittedKey, includedKeys).map(([key, child]) => ({ + label: humanizeKey(key), + value: formatValue(child), + })); +} + +function parseJsonText(value: unknown): unknown { + if (typeof value !== "string") return undefined; + try { + return JSON.parse(value) as unknown; + } catch { + return undefined; + } +} + +function unwrapMcpResult(output: unknown): unknown { + if (!isRecord(output)) return output; + + if (output.structuredContent !== undefined) { + return output.structuredContent; + } + + if (Array.isArray(output.content) && output.content.length === 1) { + const item = output.content[0]; + if (isRecord(item) && item.type === "text") { + return parseJsonText(item.text) ?? item.text; + } + } + + return output; +} + +export function buildPaseoToolDetailSections( + toolName: string, + input: unknown, + output: unknown, +): PaseoToolDetailSection[] | null { + const leafName = getPaseoToolLeafName(toolName); + if (!leafName) return null; + + const spec: PaseoToolDetailSpec = getPaseoToolEntry(leafName)?.detail ?? {}; + const sections: PaseoToolDetailSection[] = []; + if (spec.promptField && isRecord(input)) { + const prompt = input[spec.promptField]; + if (typeof prompt === "string" && prompt.length > 0) { + sections.push({ kind: "prose", title: "Prompt", text: prompt }); + } + } + + const inputFields = fieldsFromValue(input, spec.inputOrder, spec.promptField); + if (inputFields.length > 0) { + sections.push({ kind: "fields", title: "Details", fields: inputFields }); + } + + const outputFields = fieldsFromValue( + unwrapMcpResult(output), + spec.outputFields, + undefined, + spec.outputFields, + ); + if (outputFields.length > 0) { + sections.push({ kind: "fields", title: "Result", fields: outputFields }); + } + return sections; +} diff --git a/packages/protocol/src/paseo-tool-presentation/index.test.ts b/packages/protocol/src/paseo-tool-presentation/index.test.ts new file mode 100644 index 0000000000..bea9acd400 --- /dev/null +++ b/packages/protocol/src/paseo-tool-presentation/index.test.ts @@ -0,0 +1,141 @@ +import { describe, expect, it } from "vitest"; + +import { + buildAgentMessageDisplay, + buildPaseoToolDisplay, + getPaseoToolTargetAgentId, + MAX_SUMMARY_CHARS, + PASEO_TOOL_NAMES, +} from "./index.js"; + +function display(toolName: string, input: unknown, targetAgentTitle?: string) { + return buildPaseoToolDisplay({ + toolName, + detail: { type: "unknown", input, output: null }, + ...(targetAgentTitle ? { targetAgentTitle } : {}), + }); +} + +describe("Paseo tool display", () => { + it.each([ + [ + "send_agent_prompt", + { agentId: "agt_1", prompt: "Fix the failing test" }, + "Send message", + "Fix the failing test", + ], + ["create_agent", { title: "Reviewer", initialPrompt: "Review it" }, "Create agent", "Reviewer"], + ["create_agent", { initialPrompt: "Review it" }, "Create agent", "Review it"], + ["get_agent_status", { agentId: "agt_1" }, "Check agent", "agt_1"], + ["update_agent", { agentId: "agt_1", name: "Renamed" }, "Update agent", "Renamed"], + ["create_workspace", { path: "/tmp/repo/feature-x" }, "Create workspace", "feature-x"], + ["create_workspace", { title: "Docs", branchName: "docs" }, "Create workspace", "Docs"], + ["start_workspace_script", { scriptName: "web" }, "Start script", "web"], + ["send_terminal_keys", { terminalId: "t1", keys: "npm test" }, "Send keys", "npm test"], + ["create_schedule", { prompt: "Check CI", cron: "0 9 * * 1" }, "Create schedule", "0 9 * * 1"], + ["browser_navigate", { url: "https://paseo.sh" }, "Navigate", "https://paseo.sh"], + [ + "browser_upload", + { ref: "@e1", filePaths: ["/a.png", "/b.png"] }, + "Upload files", + "/a.png +1", + ], + ["browser_resize", { width: 800, height: 600 }, "Resize browser", "800×600"], + ])("presents %s with a fixed label and its context", (tool, input, label, summary) => { + expect(display(`mcp__paseo__${tool}`, input)).toEqual({ displayName: label, summary }); + }); + + it("omits the summary when a call has no context", () => { + expect(display("mcp__paseo__list_agents", {})).toEqual({ displayName: "List agents" }); + }); + + it("recognizes every Paseo namespace format", () => { + for (const name of ["mcp__paseo__kill_agent", "paseo.kill_agent", "paseo_remote.kill_agent"]) { + expect(display(name, { agentId: "agt_1" })?.displayName).toBe("Kill agent"); + } + }); + + it("returns null outside the Paseo namespace, including speak", () => { + expect(display("Bash", {})).toBeNull(); + expect(display("mcp__paseo__speak", { text: "hi" })).toBeNull(); + }); + + it("humanizes a Paseo tool that has no catalog entry", () => { + expect(display("mcp__paseo__brand_new_tool", {})).toEqual({ displayName: "Brand new tool" }); + }); + + it("prefers the known agent title over the agent ID", () => { + expect(display("mcp__paseo__cancel_agent", { agentId: "agt_1" }, "Reviewer")).toEqual({ + displayName: "Cancel agent", + summary: "Reviewer", + }); + expect( + getPaseoToolTargetAgentId("mcp__paseo__cancel_agent", { + type: "unknown", + input: { agentId: "agt_1" }, + output: null, + }), + ).toBe("agt_1"); + expect( + getPaseoToolTargetAgentId("Bash", { type: "unknown", input: { agentId: "x" }, output: null }), + ).toBeNull(); + }); + + it("truncates a massive single-line prompt and collapses whitespace", () => { + const prompt = `Line one\n\n line two ${"x".repeat(1_000_000)}`; + const summary = display("mcp__paseo__send_agent_prompt", { agentId: "a", prompt })?.summary; + expect(summary).toHaveLength(MAX_SUMMARY_CHARS); + expect(summary?.startsWith("Line one line two xxx")).toBe(true); + expect(summary?.endsWith("…")).toBe(true); + }); + + it("bounds the scan even when the prompt opens with a wall of whitespace", () => { + const prompt = `${" ".repeat(10_000)}hidden`; + const summary = display("mcp__paseo__send_agent_prompt", { agentId: "a", prompt })?.summary; + expect(summary).toBeUndefined(); + }); + + it("keeps a short prompt intact", () => { + expect( + display("mcp__paseo__send_agent_prompt", { agentId: "a", prompt: " hi\nthere " })?.summary, + ).toBe("hi there"); + }); + + it("catalogs tool names as lowercase leaf names", () => { + for (const name of PASEO_TOOL_NAMES) { + expect(name).toMatch(/^[a-z_]+$/); + } + }); +}); + +describe("agent message display", () => { + it.each([ + ["message", "Message received"], + ["finished", "Agent finished"], + ["errored", "Agent errored"], + ["permission-required", "Agent needs permission"], + ["closed", "Agent closed"], + ] as const)("labels %s noun-first with the sender as context", (event, label) => { + const result = buildAgentMessageDisplay({ + event, + sender: { id: "srv::agt_1", title: "QA messenger" }, + text: "Done.", + }); + expect(result.displayName).toBe(label); + expect(result.summary).toBe("QA messenger"); + expect(result.detail).toEqual({ type: "plain_text", text: "From agent: srv::agt_1\n\nDone." }); + }); + + it("falls back to the sender ID and truncates a long title", () => { + expect( + buildAgentMessageDisplay({ event: "finished", sender: { id: "srv::agt_1" }, text: "" }) + .summary, + ).toBe("srv::agt_1"); + const summary = buildAgentMessageDisplay({ + event: "finished", + sender: { id: "a", title: "t".repeat(500) }, + text: "", + }).summary; + expect(summary).toHaveLength(MAX_SUMMARY_CHARS); + }); +}); diff --git a/packages/protocol/src/paseo-tool-presentation/index.ts b/packages/protocol/src/paseo-tool-presentation/index.ts new file mode 100644 index 0000000000..c04606a231 --- /dev/null +++ b/packages/protocol/src/paseo-tool-presentation/index.ts @@ -0,0 +1,85 @@ +import type { ToolCallDetail } from "../agent-types.js"; +import { getPaseoToolLeafName, isPaseoToolName } from "../tool-name-normalization.js"; +import { getPaseoToolEntry, PASEO_TOOL_CATALOG, type PaseoToolName } from "./catalog.js"; +import { toSummaryText } from "./summary-text.js"; + +export { buildAgentMessageDisplay, type AgentMessageDisplay } from "./agent-message.js"; +export { + buildPaseoToolDetailSections, + type PaseoToolDetailField, + type PaseoToolDetailSection, +} from "./detail-sections.js"; +export { MAX_SUMMARY_CHARS } from "./summary-text.js"; +export type { PaseoToolName }; + +export interface PaseoToolDisplayInput { + toolName: string; + detail: ToolCallDetail; + /** Title of the agent named by the call's `agentId`, when the caller knows it. */ + targetAgentTitle?: string; +} + +export interface PaseoToolDisplay { + displayName: string; + summary?: string; +} + +export const PASEO_TOOL_NAMES = Object.keys(PASEO_TOOL_CATALOG) as readonly PaseoToolName[]; + +/** Returns null for tools outside the Paseo namespace. */ +export function buildPaseoToolDisplay(input: PaseoToolDisplayInput): PaseoToolDisplay | null { + const leafName = paseoLeafName(input.toolName); + if (!leafName) return null; + const entry = getPaseoToolEntry(leafName); + if (!entry) return { displayName: humanizeLeafName(leafName) }; + + const toolInput = readToolInput(input.detail); + const targetAgent = input.targetAgentTitle ?? readString(toolInput.agentId); + const summary = formatContext(entry.context?.(toolInput, targetAgent)); + return { displayName: entry.label, ...(summary ? { summary } : {}) }; +} + +/** The agent a Paseo call acts on, so callers can resolve its title. */ +export function getPaseoToolTargetAgentId( + toolName: string, + detail: ToolCallDetail | undefined, +): string | null { + if (!detail || !paseoLeafName(toolName)) return null; + return readString(readToolInput(detail).agentId) ?? null; +} + +function paseoLeafName(toolName: string): string | null { + return isPaseoToolName(toolName) ? getPaseoToolLeafName(toolName) : null; +} + +function readToolInput(detail: ToolCallDetail): Readonly> { + if (detail.type !== "unknown") return {}; + const value = detail.input; + return typeof value === "object" && value !== null && !Array.isArray(value) + ? (value as Record) + : {}; +} + +function readString(value: unknown): string | undefined { + return typeof value === "string" && value.length > 0 ? value : undefined; +} + +function formatContext(value: unknown): string | undefined { + if (typeof value === "string") return toSummaryText(value); + if (typeof value === "number") return String(value); + if (Array.isArray(value)) { + const [first, ...rest] = value; + const head = typeof first === "string" ? toSummaryText(first) : undefined; + if (!head) return undefined; + return rest.length > 0 ? `${head} +${rest.length}` : head; + } + return undefined; +} + +function humanizeLeafName(leafName: string): string { + const sentence = leafName + .replace(/[._-]+/g, " ") + .trim() + .toLowerCase(); + return `${sentence[0]?.toUpperCase() ?? ""}${sentence.slice(1)}`; +} diff --git a/packages/protocol/src/paseo-tool-presentation/summary-text.ts b/packages/protocol/src/paseo-tool-presentation/summary-text.ts new file mode 100644 index 0000000000..57e7405771 --- /dev/null +++ b/packages/protocol/src/paseo-tool-presentation/summary-text.ts @@ -0,0 +1,21 @@ +/** + * Prompts and results can be one enormous line. Summaries are capped here so no + * consumer relies on its renderer to clip them. + */ +export const MAX_SUMMARY_CHARS = 120; +// Bounds the whitespace scan: inputs can be megabytes. +const SCAN_WINDOW_CHARS = MAX_SUMMARY_CHARS * 4; + +export function toSummaryText(value: string): string | undefined { + const isPartial = value.length > SCAN_WINDOW_CHARS; + const collapsed = value.slice(0, SCAN_WINDOW_CHARS).replace(/\s+/g, " ").trim(); + if (!collapsed) return undefined; + if (collapsed.length <= MAX_SUMMARY_CHARS && !isPartial) return collapsed; + const kept = dropTrailingHighSurrogate(collapsed.slice(0, MAX_SUMMARY_CHARS - 1)).trimEnd(); + return `${kept}…`; +} + +function dropTrailingHighSurrogate(text: string): string { + const last = text.charCodeAt(text.length - 1); + return last >= 0xd800 && last <= 0xdbff ? text.slice(0, -1) : text; +} diff --git a/packages/protocol/src/provider-icon-names.ts b/packages/protocol/src/provider-icon-names.ts index 4ca8ea44e3..5f707dfeff 100644 --- a/packages/protocol/src/provider-icon-names.ts +++ b/packages/protocol/src/provider-icon-names.ts @@ -1,4 +1,5 @@ export const BUILTIN_PROVIDER_ICON_NAMES = [ + "antigravity", "claude", "codex", "copilot", @@ -22,6 +23,7 @@ export const ACP_PROVIDER_ICON_NAMES = [ "crow-cli", "cursor", "deepagents", + "devin", "dimcode", "dirac", "factory-droid", @@ -31,6 +33,7 @@ export const ACP_PROVIDER_ICON_NAMES = [ "glm-acp-agent", "goose", "grok", + "hermes", "hoplite", "junie", "kilo", diff --git a/packages/protocol/src/tool-call-display.ts b/packages/protocol/src/tool-call-display.ts index ab597b5acd..db0aa6db20 100644 --- a/packages/protocol/src/tool-call-display.ts +++ b/packages/protocol/src/tool-call-display.ts @@ -1,6 +1,8 @@ -import { buildAgentMessageDisplay } from "./agent-message-display.js"; import type { ToolCallTimelineItem } from "./agent-types.js"; -import { getPaseoToolLeafName, isPaseoToolName } from "./tool-name-normalization.js"; +import { + buildAgentMessageDisplay, + buildPaseoToolDisplay, +} from "./paseo-tool-presentation/index.js"; import { stripCwdPrefix } from "./path-utils.js"; export type ToolCallDisplayInput = Pick< @@ -8,6 +10,8 @@ export type ToolCallDisplayInput = Pick< "name" | "status" | "error" | "metadata" | "detail" | "agentMessage" > & { cwd?: string; + /** Title of the agent a Paseo call targets, when the caller knows it. */ + targetAgentTitle?: string; }; export interface ToolCallDisplayModel { @@ -34,12 +38,6 @@ function humanizeToolName(name: string): string { if (!trimmed) { return name; } - if (isPaseoToolName(trimmed)) { - const leaf = getPaseoToolLeafName(trimmed); - if (leaf) { - return humanizeToolName(leaf); - } - } if (/[:./]/.test(trimmed) || trimmed.includes("__")) { return trimmed; } @@ -152,8 +150,20 @@ function buildUnknownDetailOverride(input: ToolCallDisplayInput): DetailDisplay } export function buildToolCallDisplayModel(input: ToolCallDisplayInput): ToolCallDisplayModel { - if (input.agentMessage) { - return { displayName: buildAgentMessageDisplay(input.agentMessage).displayName }; + const errorText = input.status === "failed" ? formatErrorText(input.error) : undefined; + const paseoDisplay = input.agentMessage + ? buildAgentMessageDisplay(input.agentMessage) + : buildPaseoToolDisplay({ + toolName: input.name, + detail: input.detail, + targetAgentTitle: input.targetAgentTitle, + }); + if (paseoDisplay) { + return { + displayName: paseoDisplay.displayName, + ...(paseoDisplay.summary ? { summary: paseoDisplay.summary } : {}), + ...(errorText ? { errorText } : {}), + }; } const canonicalDisplay = buildCanonicalDetailDisplay(input); const unknownDetailOverride = buildUnknownDetailOverride(input); @@ -162,7 +172,6 @@ export function buildToolCallDisplayModel(input: ToolCallDisplayInput): ToolCall canonicalDisplay.displayName ?? humanizeToolName(input.name); const summary = unknownDetailOverride.summary ?? canonicalDisplay.summary; - const errorText = input.status === "failed" ? formatErrorText(input.error) : undefined; return { displayName, diff --git a/packages/relay/package.json b/packages/relay/package.json index c182f2c403..3cadb9c3e0 100644 --- a/packages/relay/package.json +++ b/packages/relay/package.json @@ -1,6 +1,6 @@ { "name": "@getpaseo/relay", - "version": "0.12.0-beta.1", + "version": "0.12.0", "description": "Paseo relay for bridging daemon and client connections", "files": [ "dist", diff --git a/packages/server/package.json b/packages/server/package.json index 1116605bf4..afc1c4a399 100644 --- a/packages/server/package.json +++ b/packages/server/package.json @@ -1,6 +1,6 @@ { "name": "@getpaseo/server", - "version": "0.12.0-beta.1", + "version": "0.12.0", "description": "Paseo backend server", "files": [ "dist/server", @@ -89,7 +89,7 @@ "speech:transcribe:local": "tsx scripts/transcribe-local-wav.ts", "test": "npm run test:unit && npm run test:integration", "test:unit": "vitest run --fileParallelism --exclude \"**/*.e2e.test.ts\"", - "test:integration": "vitest run --maxWorkers=1 src/server/git-filename-diffs.e2e.test.ts src/server/daemon-e2e/checkout-diff-content.e2e.test.ts src/server/daemon-e2e/filesystem.e2e.test.ts src/server/daemon-e2e/file-download.e2e.test.ts src/server/daemon-e2e/cli-logs-follow.e2e.test.ts src/server/creation/creation.e2e.test.ts src/server/daemon-e2e/terminal-workspace-sdk.e2e.test.ts src/server/workspace-create-worktree-source.e2e.test.ts src/server/daemon-e2e/models.e2e.test.ts src/server/daemon-e2e/live-preferences.e2e.test.ts src/server/daemon-e2e/oversized-message.e2e.test.ts src/server/agent/model-catalog.e2e.test.ts src/server/plugins/plugin-paseo-api.e2e.test.ts && vitest run --maxWorkers=1 src/server/daemon-e2e/git-operations.e2e.test.ts -t \"merges into\" && vitest run --maxWorkers=1 src/server/session.create-agent-worktree-autoarchive.e2e.test.ts -t \"creates a worktree and auto-archives both\" && vitest run --maxWorkers=1 src/server/agent/providers/opencode-bridge.local.e2e.test.ts -t \"versioned runtime\" && vitest run --maxWorkers=1 src/server/daemon-e2e/relay-transport.e2e.test.ts -t \"oversized attachments\"", + "test:integration": "vitest run --maxWorkers=1 src/server/git-filename-diffs.e2e.test.ts src/server/daemon-e2e/checkout-diff-content.e2e.test.ts src/server/daemon-e2e/filesystem.e2e.test.ts src/server/daemon-e2e/file-download.e2e.test.ts src/server/daemon-e2e/cli-logs-follow.e2e.test.ts src/server/creation/creation.e2e.test.ts src/server/daemon-e2e/terminal-workspace-sdk.e2e.test.ts src/server/workspace-create-worktree-source.e2e.test.ts src/server/daemon-e2e/models.e2e.test.ts src/server/daemon-e2e/live-preferences.e2e.test.ts src/server/daemon-e2e/oversized-message.e2e.test.ts src/server/agent/model-catalog.e2e.test.ts src/server/plugins/plugin-paseo-api.e2e.test.ts && vitest run --maxWorkers=1 src/server/daemon-e2e/git-operations.e2e.test.ts src/server/session.create-agent-worktree-autoarchive.e2e.test.ts src/server/agent/providers/opencode-bridge.local.e2e.test.ts src/server/daemon-e2e/relay-transport.e2e.test.ts -t \"merges into|creates a worktree and auto-archives both|versioned runtime|oversized attachments\"", "test:hub-cli-contract": "vitest run --maxWorkers=1 src/server/hub/hub-cli-contract.test.ts", "test:integration:all": "npm run test:e2e", "test:integration:real": "vitest run real.e2e.test.ts", @@ -107,11 +107,11 @@ "@agentclientprotocol/sdk": "^0.17.1", "@anthropic-ai/claude-agent-sdk": "0.3.246", "@anthropic-ai/sdk": "^0.104.2", - "@getpaseo/client": "0.12.0-beta.1", - "@getpaseo/highlight": "0.12.0-beta.1", - "@getpaseo/plugin": "0.12.0-beta.1", - "@getpaseo/protocol": "0.12.0-beta.1", - "@getpaseo/relay": "0.12.0-beta.1", + "@getpaseo/client": "0.12.0", + "@getpaseo/highlight": "0.12.0", + "@getpaseo/plugin": "0.12.0", + "@getpaseo/protocol": "0.12.0", + "@getpaseo/relay": "0.12.0", "@isaacs/ttlcache": "^2.1.4", "@modelcontextprotocol/sdk": "1.29.0", "@opencode-ai/sdk": "1.14.46", diff --git a/packages/server/scripts/measure-file-observer.test.ts b/packages/server/scripts/measure-file-observer.test.ts new file mode 100644 index 0000000000..345da462bb --- /dev/null +++ b/packages/server/scripts/measure-file-observer.test.ts @@ -0,0 +1,59 @@ +import { execFile } from "node:child_process"; +import { mkdtemp, rm } from "node:fs/promises"; +import { tmpdir } from "node:os"; +import { join } from "node:path"; +import { fileURLToPath } from "node:url"; +import { promisify } from "node:util"; +import { expect, test } from "vitest"; + +const execFileAsync = promisify(execFile); + +// Linux delivers the existing inventory as one batch. Other backends have +// different startup semantics, so they do not exercise this regression. +test.skipIf(process.platform !== "linux").each(["healthy", "directory-churn"])( + "%s benchmark collects a startup batch larger than the argument limit", + async (mode) => { + const temporaryRoot = await mkdtemp(join(tmpdir(), "paseo-watch-benchmark-test-")); + try { + const { stdout } = await execFileAsync( + process.execPath, + [ + // Lower the argument limit instead of creating hundreds of thousands + // of files. This still runs the real observer and benchmark CLI. + "--stack-size=256", + "--import", + "tsx", + fileURLToPath(new URL("./measure-file-observer.ts", import.meta.url)), + "--child", + ], + { + timeout: 60_000, + env: { + ...process.env, + TMPDIR: temporaryRoot, + PASEO_WATCH_BENCH_MODE: mode, + PASEO_WATCH_BENCH_ROOTS: "1", + PASEO_WATCH_BENCH_DIRS: "10", + PASEO_WATCH_BENCH_PREEXISTING_FILES: "40000", + PASEO_WATCH_BENCH_IGNORED_FILES: "1", + PASEO_WATCH_BENCH_EDITS: "1", + PASEO_WATCH_BENCH_SUSTAINED_EDITS: "1", + PASEO_WATCH_BENCH_SUSTAINED_INTERVAL_MS: "1", + PASEO_WATCH_BENCH_CHURN_DIRECTORIES: "10", + PASEO_WATCH_BENCH_CHURN_FILES_PER_DIRECTORY: "4000", + PASEO_WATCH_BENCH_CHURN_ROUNDS: "1", + PASEO_WATCH_BENCH_CHURN_DIRECTORIES_PER_ROUND: "2", + }, + }, + ); + const measurement = JSON.parse(stdout); + expect(measurement.startupEvents).toBe(40_000); + expect(measurement.deliveredEvents).toBeGreaterThan(measurement.startupEvents); + expect(measurement.missedTrackedPaths).toBe(0); + expect(measurement.ignoredEvents).toBe(0); + } finally { + await rm(temporaryRoot, { recursive: true, force: true }); + } + }, + 90_000, +); diff --git a/packages/server/scripts/measure-file-observer.ts b/packages/server/scripts/measure-file-observer.ts index 49a54faf4d..2e37f9a414 100644 --- a/packages/server/scripts/measure-file-observer.ts +++ b/packages/server/scripts/measure-file-observer.ts @@ -199,8 +199,8 @@ async function measure(run: number): Promise { root, (nextError, events) => { error ??= nextError; - delivered.push(...events); for (const event of events) { + delivered.push(event); if (!firstObservedAt.has(event.path)) firstObservedAt.set(event.path, performance.now()); } @@ -456,7 +456,7 @@ async function measureDirectoryChurn(run: number): Promise { const setupStarted = performance.now(); subscription = await observer.subscribe(root, (nextError, events) => { error ??= nextError; - delivered.push(...events); + for (const event of events) delivered.push(event); }); const setupMs = performance.now() - setupStarted; diff --git a/packages/server/src/server/agent/activity-curator.test.ts b/packages/server/src/server/agent/activity-curator.test.ts index 58a8a8b4f1..77814f1779 100644 --- a/packages/server/src/server/agent/activity-curator.test.ts +++ b/packages/server/src/server/agent/activity-curator.test.ts @@ -2,6 +2,7 @@ import { describe, expect, it } from "vitest"; import { buildAgentForkContextAttachment, curateAgentActivity } from "./activity-curator.js"; import type { AgentTimelineItem } from "./agent-sdk-types.js"; import type { AgentTimelineRow } from "./agent-timeline-store-types.js"; +import { formatAgentMessage, projectAgentMessage } from "./agent-messages/index.js"; function toolCallItem(params: { callId: string; @@ -78,6 +79,28 @@ describe("curateAgentActivity", () => { ); }); + it("renders delivered agent messages with their event, sender, and body", () => { + const delivered = (source: Parameters[0]["source"], text: string) => + projectAgentMessage({ + type: "user_message", + text: formatAgentMessage({ id: `msg-${text.length}`, source, text }), + })!; + const timeline: AgentTimelineItem[] = [ + delivered( + { kind: "agent-message", agentId: "agt_lead", title: "CI lead" }, + "Take ownership.\nRead the handoff.", + ), + delivered( + { kind: "agent-notification", agentId: "agt_child", event: "finished" }, + "Child is done.", + ), + ]; + + expect(curateAgentActivity(timeline)).toBe( + "[Message received] CI lead\nTake ownership.\nRead the handoff.\n[Agent finished] agt_child\nChild is done.", + ); + }); + it("renders user/assistant/reasoning entries", () => { const timeline: AgentTimelineItem[] = [ { type: "user_message", text: "Hello" }, diff --git a/packages/server/src/server/agent/activity-curator.ts b/packages/server/src/server/agent/activity-curator.ts index efd0a8e48d..ec5bceb1cb 100644 --- a/packages/server/src/server/agent/activity-curator.ts +++ b/packages/server/src/server/agent/activity-curator.ts @@ -1,7 +1,9 @@ import type { AgentTimelineItem } from "./agent-sdk-types.js"; +import type { AgentMessage } from "@getpaseo/protocol/agent-message"; import type { AgentAttachment } from "@getpaseo/protocol/messages"; import type { AgentTimelineRow } from "./agent-timeline-store-types.js"; import { isLikelyExternalToolName } from "@getpaseo/protocol/tool-name-normalization"; +import { buildAgentMessageDisplay } from "@getpaseo/protocol/paseo-tool-presentation/index"; import { buildToolCallDisplayModel } from "@getpaseo/protocol/tool-call-display"; import { projectTimelineRows } from "./timeline-projection.js"; @@ -119,6 +121,17 @@ function formatToolCallEntry( return activityEntry(summary ? `[${displayName}] ${summary}` : `[${displayName}]`); } +function appendAgentMessageEntries(entries: ActivityEntry[], message: AgentMessage) { + const display = buildAgentMessageDisplay(message); + entries.push( + activityEntry( + display.summary ? `[${display.displayName}] ${display.summary}` : `[${display.displayName}]`, + ), + ); + const body = message.text.trim(); + if (body) entries.push(activityEntry(body)); +} + function curateProjectedActivityEntries( items: readonly AgentTimelineItem[], options?: ActivityCuratorOptions, @@ -146,6 +159,10 @@ function curateProjectedActivityEntries( appendTextEntry(entries, item, options); break; case "tool_call": { + if (item.agentMessage) { + appendAgentMessageEntries(entries, item.agentMessage); + break; + } entries.push(formatToolCallEntry(item, options)); if (item.detail.type === "sub_agent" && item.detail.log.trim()) { entries.push(activityEntry(item.detail.log.trim())); diff --git a/packages/server/src/server/agent/agent-manager.ts b/packages/server/src/server/agent/agent-manager.ts index ff91ef85ef..a15d94389f 100644 --- a/packages/server/src/server/agent/agent-manager.ts +++ b/packages/server/src/server/agent/agent-manager.ts @@ -3654,6 +3654,8 @@ export class AgentManager { this.assertAgentRegistrationActive(managed); this.emitState(managed, { persist: false }); this.subscribeToSession(managed); + await this.drainSessionEvents(managed.id); + this.assertAgentRegistrationActive(managed); return { ...managed }; } catch (error) { if (!registered) { diff --git a/packages/server/src/server/agent/agent-sdk-types.ts b/packages/server/src/server/agent/agent-sdk-types.ts index 34d36c9e16..59fb6022e9 100644 --- a/packages/server/src/server/agent/agent-sdk-types.ts +++ b/packages/server/src/server/agent/agent-sdk-types.ts @@ -8,6 +8,7 @@ import type { ProviderOptions, ToolPolicy, } from "@getpaseo/protocol/agent-types"; +import type { AgentMessage } from "@getpaseo/protocol/agent-message"; import type { AgentAttachment } from "@getpaseo/protocol/messages"; import type { PaseoToolCatalog } from "./tools/types.js"; @@ -342,6 +343,8 @@ interface ToolCallBase { name: string; detail: ToolCallDetail; metadata?: Record; + /** Set when the row is a delivered agent message rather than a provider tool call. */ + agentMessage?: AgentMessage; } type ToolCallRunningTimelineItem = ToolCallBase & { diff --git a/packages/server/src/server/agent/mcp-server.test.ts b/packages/server/src/server/agent/mcp-server.test.ts index 9246f463d0..6e093a18a4 100644 --- a/packages/server/src/server/agent/mcp-server.test.ts +++ b/packages/server/src/server/agent/mcp-server.test.ts @@ -64,8 +64,10 @@ import { createGitMutationService } from "../session/git-mutation/git-mutation-s import type { GeneratedWorkspaceName } from "../worktree-branch-name-generator.js"; import type { ForgeService } from "../../services/forge-service.js"; import { areEquivalentPaths } from "../../utils/path.js"; -import type { TerminalManager } from "../../terminal/terminal-manager.js"; +import { createTerminalManager, type TerminalManager } from "../../terminal/terminal-manager.js"; +import { createWorkerTerminalManager } from "../../terminal/worker-terminal-manager.js"; import { PARENT_AGENT_ID_LABEL } from "@getpaseo/protocol/agent-labels"; +import { PASEO_TOOL_NAMES } from "@getpaseo/protocol/paseo-tool-presentation/index"; import { MutableDaemonConfigSchema, type AgentProfile } from "@getpaseo/protocol/messages"; import type { DaemonConfigStore } from "../daemon-config-store.js"; import type { BrowserToolsBroker, BrowserToolsExecuteInput } from "../browser-tools/broker.js"; @@ -888,6 +890,40 @@ describe("bundled Paseo skill", () => { }); }); +describe("Paseo tool timeline presentation", () => { + it("catalogs a timeline label for every advertised tool", async () => { + const server = await createAgentMcpServer({ + agentManager: new BoundaryAgentManagerFake() as AgentManager, + agentStorage: new BoundaryAgentStorageFake() as AgentStorage, + providerSnapshotManager: + new BoundaryProviderSnapshotManagerFake() as unknown as ProviderSnapshotManager, + browserToolsEnabled: true, + browserToolsBroker: new FakeBrowserToolsBroker({ + requestId: "req-catalog", + ok: true, + result: { command: "list_tabs", tabs: [] }, + }) as BrowserToolsBroker, + callerAgentId: "agent-1", + logger: createTestLogger(), + }); + const client = await connectInMemoryMcpClient(server); + + try { + const { tools } = await client.listTools(); + const cataloged = new Set(PASEO_TOOL_NAMES); + // speak renders as a voice message, not a tool call row. + const uncataloged = tools + .map((tool) => tool.name) + .filter((name) => name !== "speak" && !cataloged.has(name)); + expect(tools.length).toBeGreaterThan(40); + expect(uncataloged).toEqual([]); + } finally { + await client.close(); + await server.close(); + } + }); +}); + describe("browser MCP tools", () => { const logger = createTestLogger(); @@ -1216,6 +1252,168 @@ describe("browser MCP tools", () => { describe("terminal MCP tools", () => { const logger = createTestLogger(); + it.each<[string, string, string, boolean]>([ + ["Down", "\x1b[B", "", false], + ["Up", "\x1b[A", "", false], + ["Left", "\x1b[D", "", false], + ["Right", "\x1b[C", "", false], + ["PageUp", "\x1b[5~", "", false], + ["PageDown", "\x1b[6~", "", false], + ["Home", "\x1b[H", "", false], + ["End", "\x1b[F", "", false], + ["Insert", "\x1b[2~", "", false], + ["Delete", "\x1b[3~", "", false], + ["F1", "\x1bOP", "", false], + ["F5", "\x1b[15~", "", false], + ["F12", "\x1b[24~", "", false], + ["S-Tab", "\x1b[Z", "", false], + ["C-r", "\x12", "", false], + ["M-b", "\x1bb", "", false], + ["C-M-Left", "\x1b[1;7D", "", false], + ["C-S-Up", "\x1b[1;6A", "", false], + ["C-Space", "\x00", "", false], + ["Enter", "\r", "", false], + ["Tab", "\t", "", false], + ["Escape", "\x1b", "", false], + ["Space", " ", "", false], + ["BSpace", "\x7f", "", false], + ["C-c", "\x03", "", false], + ["C-d", "\x04", "", false], + ["C-z", "\x1a", "", false], + ["C-l", "\x0c", "", false], + ["C-a", "\x01", "", false], + ["C-e", "\x05", "", false], + ["Down", "\x1bOB", "\x1b[?1h", false], + ["S-Enter", "\x1b[13;2u", "\x1b[=1;1u", false], + ["C-Enter", "\x1b[13;28;13;1;8;1_", "\x1b[?9001h", false], + ["echo hello\r", "echo hello\r", "", false], + ["\x1b[B", "\x1b[B", "", false], + ["UnknownKey", "UnknownKey", "", false], + ["constructor", "constructor", "", false], + ["__proto__", "__proto__", "", false], + ["", "", "", false], + ["Down", "Down", "\x1b[?1h", true], + ["C-r", "C-r", "", true], + ["S-Tab", "S-Tab", "", true], + ])( + "sends terminal token %j as %j (preamble=%j, literal=%s)", + async (keys, data, preamble, literal) => { + const { agentManager, agentStorage } = createTestDeps(); + const send = vi.fn(); + const terminalManager = createTerminalManagerStub({ + getTerminal: vi.fn().mockReturnValue({ + send, + getReplayPreamble: () => preamble, + }), + }); + const server = await createAgentMcpServer({ + agentManager, + agentStorage, + providerSnapshotManager: createClaudeOnlyManager(), + terminalManager, + logger, + }); + + try { + const response = await registeredTool(server, "send_terminal_keys").handler({ + terminalId: "term-1", + keys, + literal, + }); + expect(response.structuredContent).toEqual({ success: true }); + expect(send).toHaveBeenCalledExactlyOnceWith({ type: "input", data }); + } finally { + await server.close(); + } + }, + ); + + it.each([ + ["in-process", createTerminalManager], + ["worker", createWorkerTerminalManager], + ] as const)( + "delivers MCP key tokens through %s after terminal input modes change", + async (_name, createManager) => { + const { agentManager, agentStorage } = createTestDeps(); + const terminalManager = createManager(); + const terminal = await terminalManager.createTerminal({ + cwd: process.cwd(), + workspaceId: "ws-terminal-keys", + command: process.execPath, + args: [ + "-e", + `process.stdin.setRawMode(true); + process.stdout.write("READY\\r\\n"); + process.stdin.on("data", data => { + if (data.toString() === "application") { + process.stdout.write("\\x1b[?1hAPPLICATION_READY\\r\\n"); + return; + } + if (data.toString() === "normal") { + process.stdout.write("\\x1b[?1lNORMAL_READY\\r\\n"); + return; + } + process.stdout.write("HEX:" + data.toString("hex") + "\\r\\n"); + });`, + ], + }); + const server = await createAgentMcpServer({ + agentManager, + agentStorage, + providerSnapshotManager: createClaudeOnlyManager(), + terminalManager, + logger, + }); + + let output = ""; + const unsubscribe = terminal.subscribe((message) => { + if (message.type === "output") { + output += message.data; + } + }); + try { + await vi.waitFor( + async () => { + const capture = await terminalManager.captureTerminal(terminal.id); + expect(capture.lines).toContain("READY"); + }, + { timeout: 5000 }, + ); + const tool = registeredTool(server, "send_terminal_keys"); + await tool.handler({ terminalId: terminal.id, keys: "application", literal: true }); + await vi.waitFor(() => expect(output).toContain("APPLICATION_READY")); + for (const [keys, hex] of [ + ["Down", "1b4f42"], + ["Up", "1b4f41"], + ["Left", "1b4f44"], + ["Right", "1b4f43"], + ["PageDown", "1b5b367e"], + ["S-Tab", "1b5b5a"], + ["C-r", "12"], + ["M-b", "1b62"], + ]) { + await tool.handler({ terminalId: terminal.id, keys }); + await vi.waitFor(async () => { + const capture = await terminalManager.captureTerminal(terminal.id); + expect(capture.lines.join("\n")).toContain(`HEX:${hex}`); + }); + } + await tool.handler({ terminalId: terminal.id, keys: "normal", literal: true }); + await vi.waitFor(() => expect(output).toContain("NORMAL_READY")); + await tool.handler({ terminalId: terminal.id, keys: "Down" }); + await vi.waitFor(async () => { + const capture = await terminalManager.captureTerminal(terminal.id); + expect(capture.lines).toContain("HEX:1b5b42"); + }); + } finally { + unsubscribe(); + await server.close(); + await terminalManager.killTerminalAndWait(terminal.id); + terminalManager.killAll(); + } + }, + ); + it("captures terminal output through the terminal manager authority", async () => { const { agentManager, agentStorage } = createTestDeps(); const captureTerminal = vi.fn().mockResolvedValue({ diff --git a/packages/server/src/server/agent/plugin-provider.test.ts b/packages/server/src/server/agent/plugin-provider.test.ts index ae8ed805d7..aa0aa1a924 100644 --- a/packages/server/src/server/agent/plugin-provider.test.ts +++ b/packages/server/src/server/agent/plugin-provider.test.ts @@ -761,6 +761,72 @@ describe("PluginAgentClientRegistry", () => { await expect.poll(harness.closeCount).toBe(1); expect(harness.inputs.map((input) => input.type)).toContain("session.close"); }); + + test("delivers a supported steer to the active turn", async () => { + const harness = createProviderHarness({ + capabilities: [...CAPABILITIES, "prompt.steer"], + handleInput: async (input, emit) => { + if (input.type !== "session.prompt") return false; + emit({ + type: "session.prompt_result", + sessionId: input.sessionId, + clientMessageId: input.prompt.clientMessageId, + result: { type: "steer", turnId: "turn-1" }, + }); + return true; + }, + }); + const registry = new PluginAgentClientRegistry(createTestLogger()); + registry.replace([harness.registration]); + const client = registry.clients()[harness.registration.id]!; + const session = await client.createSession({ provider: harness.registration.id, cwd: "/tmp" }); + try { + await expect( + session.steerActiveTurn!("follow up", { + expectedTurnId: "turn-1", + clientMessageId: "steer-1", + clearPendingPermissions: true, + }), + ).resolves.toEqual({ status: "accepted" }); + expect(harness.inputs.find((input) => input.type === "session.prompt")).toMatchObject({ + prompt: { + delivery: "steer", + clientMessageId: "steer-1", + input: { type: "message", content: [{ type: "text", text: "follow up" }] }, + clearPendingPermissions: true, + }, + }); + } finally { + await session.close(); + registry.replace([]); + } + }); + + test("returns unavailable when steering a provider without prompt.steer capability", async () => { + const harness = createProviderHarness({ + capabilities: [ + "prompt.message", + "session.configure", + "session.persistence", + "session.subsession", + "permission", + ], + }); + const registry = new PluginAgentClientRegistry(createTestLogger()); + registry.replace([harness.registration]); + const session = await registry.clients()[harness.registration.id]!.createSession({ + provider: harness.registration.id, + cwd: "/workspace", + }); + try { + const result = await session.steerActiveTurn!("hello", { expectedTurnId: "turn-1" }); + expect(result).toEqual({ status: "unavailable" }); + expect(harness.inputs.filter((input) => input.type === "session.prompt")).toHaveLength(0); + } finally { + await session.close(); + registry.replace([]); + } + }); }); type RequestKind = "session.open" | "catalog" | "session.configure" | "session.prompt"; diff --git a/packages/server/src/server/agent/plugin-provider.ts b/packages/server/src/server/agent/plugin-provider.ts index e575ff0d45..db5d7651a2 100644 --- a/packages/server/src/server/agent/plugin-provider.ts +++ b/packages/server/src/server/agent/plugin-provider.ts @@ -1175,6 +1175,9 @@ class PluginAgentSession implements AgentSession { prompt: AgentPromptInput, options: SteerActiveTurnOptions, ): Promise { + if (!this.bridge.negotiatedCapabilities.includes("prompt.steer")) { + return { status: "unavailable" }; + } const result = await this.bridge.prompt({ clientMessageId: options.clientMessageId ?? randomUUID(), delivery: "steer", diff --git a/packages/server/src/server/agent/providers/claude/agent.background-subagent.test.ts b/packages/server/src/server/agent/providers/claude/agent.background-subagent.test.ts index d0a5bf644a..4cab1a5005 100644 --- a/packages/server/src/server/agent/providers/claude/agent.background-subagent.test.ts +++ b/packages/server/src/server/agent/providers/claude/agent.background-subagent.test.ts @@ -122,7 +122,7 @@ async function collectTimelineAcrossTurns( seq: rows.length + 1, timestamp: new Date(Date.UTC(2026, 9, 4, 0, 0, rows.length)).toISOString(), item: event.item, - ...(currentTurnId ? { turnId: currentTurnId } : {}), + ...((event.turnId ?? currentTurnId) ? { turnId: event.turnId ?? currentTurnId } : {}), }); } if (event.type === "turn_completed" && ++completedTurns === turnCount) resolve(); @@ -469,122 +469,145 @@ describe("background Claude subagents", () => { }); }); - test("keeps one logged Task card when the child streams on after the parent's turn ends", async () => { - // A child can stream across the main session's turn boundary. Claude opens the next - // main-session turn with system/init; bare child frames do not open a turn. - queryFactory.mockImplementation(() => - buildQueryMock([ - { type: "system", subtype: "init", session_id: "bg-session", permissionMode: "default" }, - { - type: "assistant", - message: { - model: "claude-haiku-4-5", - content: [ - { - type: "tool_use", - id: "toolu_background", - name: "Agent", - input: { - subagent_type: "general-purpose", - description: "Count files here", - prompt: "Run ls and reply with the number of entries.", - run_in_background: true, + test.each(["before", "after"])( + "keeps one logged Task card when child tools start %s the parent finishes", + async (timing) => { + // A child can stream across the main session's turn boundary. Claude opens the next + // main-session turn with system/init; bare child frames do not open a turn. + queryFactory.mockImplementation(() => + buildQueryMock([ + { type: "system", subtype: "init", session_id: "bg-session", permissionMode: "default" }, + { + type: "assistant", + message: { + model: "claude-haiku-4-5", + content: [ + { + type: "tool_use", + id: "toolu_background", + name: "Agent", + input: { + subagent_type: "general-purpose", + description: "Count files here", + prompt: "Run ls and reply with the number of entries.", + run_in_background: true, + }, }, - }, - ], + ], + }, }, - }, - { - type: "system", - subtype: "task_started", - task_id: "bg-task", - tool_use_id: "toolu_background", - task_type: "local_agent", - subagent_type: "general-purpose", + { + type: "system", + subtype: "task_started", + task_id: "bg-task", + tool_use_id: "toolu_background", + task_type: "local_agent", + subagent_type: "general-purpose", + description: "Count files here", + prompt: "Run ls and reply with the number of entries.", + }, + { + type: "user", + message: { + role: "user", + content: [ + { + type: "tool_result", + tool_use_id: "toolu_background", + content: "Async agent launched successfully.", + }, + ], + }, + }, + ...(timing === "after" + ? [ + { type: "result", subtype: "success", usage: {}, total_cost_usd: 0 }, + { + type: "system", + subtype: "init", + session_id: "bg-session", + permissionMode: "default", + }, + ] + : []), + { + type: "assistant", + parent_tool_use_id: "toolu_background", + message: { + model: "claude-haiku-4-5", + content: [ + { + type: "tool_use", + id: "toolu_ls", + name: "Bash", + input: { command: "ls -1", description: "List files" }, + }, + ], + }, + }, + ...(timing === "before" + ? [ + { type: "result", subtype: "success", usage: {}, total_cost_usd: 0 }, + { + type: "system", + subtype: "init", + session_id: "bg-session", + permissionMode: "default", + }, + ] + : []), + { + type: "user", + parent_tool_use_id: "toolu_background", + message: { + role: "user", + content: [{ type: "tool_result", tool_use_id: "toolu_ls", content: "a\nb\nc" }], + }, + }, + { + type: "assistant", + parent_tool_use_id: "toolu_background", + message: { model: "claude-haiku-4-5", content: [{ type: "text", text: "3" }] }, + }, + { + type: "system", + subtype: "task_updated", + task_id: "bg-task", + patch: { status: "completed" }, + }, + { + type: "system", + subtype: "task_notification", + task_id: "bg-task", + tool_use_id: "toolu_background", + status: "completed", + }, + { type: "result", subtype: "success", usage: {}, total_cost_usd: 0 }, + ]), + ); + const session = await new ClaudeAgentClient({ + logger: createTestLogger(), + queryFactory, + resolveBinary: async () => "/test/claude/bin", + }).createSession({ provider: "claude", cwd: process.cwd() }); + const rows = await collectTimelineAcrossTurns(session, "delegate work", 2); + + const cards = projectTimelineRows({ rows, mode: "projected" }) + .map((entry) => entry.item) + .filter((item) => item.type === "tool_call" && item.callId === "toolu_background"); + + expect(cards).toHaveLength(1); + expect(cards[0]).toMatchObject({ + status: "completed", + detail: { + type: "sub_agent", + subAgentType: "general-purpose", description: "Count files here", - prompt: "Run ls and reply with the number of entries.", + log: "[Bash] ls -1", }, - { - type: "user", - message: { - role: "user", - content: [ - { - type: "tool_result", - tool_use_id: "toolu_background", - content: "Async agent launched successfully.", - }, - ], - }, - }, - { - type: "assistant", - parent_tool_use_id: "toolu_background", - message: { - model: "claude-haiku-4-5", - content: [ - { - type: "tool_use", - id: "toolu_ls", - name: "Bash", - input: { command: "ls -1", description: "List files" }, - }, - ], - }, - }, - { type: "result", subtype: "success", usage: {}, total_cost_usd: 0 }, - { type: "system", subtype: "init", session_id: "bg-session", permissionMode: "default" }, - { - type: "user", - parent_tool_use_id: "toolu_background", - message: { - role: "user", - content: [{ type: "tool_result", tool_use_id: "toolu_ls", content: "a\nb\nc" }], - }, - }, - { - type: "assistant", - parent_tool_use_id: "toolu_background", - message: { model: "claude-haiku-4-5", content: [{ type: "text", text: "3" }] }, - }, - { - type: "system", - subtype: "task_updated", - task_id: "bg-task", - patch: { status: "completed" }, - }, - { - type: "system", - subtype: "task_notification", - task_id: "bg-task", - tool_use_id: "toolu_background", - status: "completed", - }, - { type: "result", subtype: "success", usage: {}, total_cost_usd: 0 }, - ]), - ); - const session = await new ClaudeAgentClient({ - logger: createTestLogger(), - queryFactory, - resolveBinary: async () => "/test/claude/bin", - }).createSession({ provider: "claude", cwd: process.cwd() }); - const rows = await collectTimelineAcrossTurns(session, "delegate work", 2); - - const cards = projectTimelineRows({ rows, mode: "projected" }) - .map((entry) => entry.item) - .filter((item) => item.type === "tool_call" && item.callId === "toolu_background"); - - expect(cards).toHaveLength(1); - expect(cards[0]).toMatchObject({ - status: "completed", - detail: { - type: "sub_agent", - subAgentType: "general-purpose", - description: "Count files here", - log: "[Bash] ls -1", - }, - }); - }); + }); + }, + ); test.each([ { diff --git a/packages/server/src/server/agent/providers/claude/agent.ts b/packages/server/src/server/agent/providers/claude/agent.ts index b12ab706da..2af8983de0 100644 --- a/packages/server/src/server/agent/providers/claude/agent.ts +++ b/packages/server/src/server/agent/providers/claude/agent.ts @@ -2250,7 +2250,7 @@ class ClaudeAgentSession implements AgentSession { private readonly sidechainTracker = new ClaudeSidechainTracker({ getToolInput: (toolUseId) => this.toolUseCache.get(toolUseId)?.input ?? - this.settledSubagentToolCallInCurrentTurn(toolUseId)?.input ?? + this.settledSubagentToolCalls.get(toolUseId)?.input ?? null, // Releases that predate the task protocol announce nothing, so the tracker keeps deriving // identity and status from frames for them. Detecting the capability beats comparing version @@ -2258,13 +2258,11 @@ class ClaudeAgentSession implements AgentSession { isDescriptorOwnedElsewhere: () => this.taskProtocolSource.isActive, // A background child streams its frames after Claude has already answered the call, so its // card is rebuilt from the settled call: a running one would replace the settled, labeled card. - // A card belongs to the turn that answered the call, so frames from a later turn leave it be. + // Late card updates retain the turn that answered the call. needsSyntheticParentToolCard: (toolUseId) => - (this.toolUseCache.has(toolUseId) || - this.settledSubagentToolCallInCurrentTurn(toolUseId) !== undefined) && + (this.toolUseCache.has(toolUseId) || this.settledSubagentToolCalls.has(toolUseId)) && this.taskProtocolSource.needsSyntheticParentToolCard(toolUseId), - getSettledParentToolCall: (toolUseId) => - this.settledSubagentToolCallInCurrentTurn(toolUseId)?.item, + getSettledParentToolCall: (toolUseId) => this.settledSubagentToolCalls.get(toolUseId)?.item, }); private persistedHistory: PersistedTimelineEntry[] = []; private persistedProviderSubagentEvents: Extract< @@ -4490,7 +4488,12 @@ class ClaudeAgentSession implements AgentSession { ), ).map((event): AgentStreamEvent => ({ type: "provider_subagent", provider: "claude", event })); const routedId = canonicalSubagentId ?? parentToolUseId; - return [...runtimeEvents, ...this.sidechainTracker.handleMessage(message, routedId)]; + const settled = this.settledSubagentToolCalls.get(routedId); + const sidechainEvents = this.sidechainTracker.handleMessage(message, routedId).map((event) => { + if (event.type === "timeline" && settled?.turnId) event.turnId = settled.turnId; + return event; + }); + return [...runtimeEvents, ...sidechainEvents]; } /** @@ -5145,7 +5148,8 @@ class ClaudeAgentSession implements AgentSession { } private notifySubscribers(event: AgentStreamEvent): void { - const turnId = this.activeForegroundTurnId ?? this.autonomousTurn?.id; + const turnId = + getAgentStreamEventTurnId(event) ?? this.activeForegroundTurnId ?? this.autonomousTurn?.id; const tagged = turnId ? { ...event, turnId } : event; this.logger.trace( { @@ -5621,17 +5625,12 @@ class ClaudeAgentSession implements AgentSession { }); } - private settledSubagentToolCallInCurrentTurn(subagentId: string) { - const settled = this.settledSubagentToolCalls.get(subagentId); - const currentTurnId = this.activeForegroundTurnId ?? this.autonomousTurn?.id ?? null; - return settled && settled.turnId === currentTurnId ? settled : undefined; - } - /** A finished child streams no more frames, so its settled call has nothing left to update. */ private releaseFinishedSubagentToolCalls(observations: SubagentObservation[]): void { for (const observation of observations) { if (observation.kind === "status" && observation.status !== "running") { this.settledSubagentToolCalls.delete(observation.id); + this.sidechainTracker.delete(observation.id); } } } diff --git a/packages/server/src/server/agent/providers/claude/sidechain-tracker.test.ts b/packages/server/src/server/agent/providers/claude/sidechain-tracker.test.ts index f762557879..a17c1cd58c 100644 --- a/packages/server/src/server/agent/providers/claude/sidechain-tracker.test.ts +++ b/packages/server/src/server/agent/providers/claude/sidechain-tracker.test.ts @@ -4,6 +4,40 @@ import type { SDKMessage } from "@anthropic-ai/claude-agent-sdk"; import { ClaudeSidechainTracker } from "./sidechain-tracker.js"; describe("ClaudeSidechainTracker", () => { + it("retains a background child's actions across the parent finishing", () => { + const tracker = new ClaudeSidechainTracker({ + getToolInput: () => ({ subagent_type: "general-purpose", description: "List files" }), + isDescriptorOwnedElsewhere: () => true, + }); + const action = (id: string, command: string) => + ({ + type: "assistant", + parent_tool_use_id: "task-1", + message: { content: [{ type: "tool_use", id, name: "Bash", input: { command } }] }, + }) as unknown as SDKMessage; + tracker.handleMessage(action("ls", "ls -1"), "task-1"); + expect(tracker.finishAll("completed")).toEqual([]); + const events = tracker.handleMessage(action("pwd", "pwd"), "task-1"); + expect(events).toContainEqual( + expect.objectContaining({ + type: "timeline", + item: expect.objectContaining({ + detail: expect.objectContaining({ log: "[Bash] ls -1\n[Bash] pwd" }), + }), + }), + ); + tracker.delete("task-1"); + const next = tracker.handleMessage(action("next", "ls"), "task-1"); + expect(next).toContainEqual( + expect.objectContaining({ + type: "timeline", + item: expect.objectContaining({ + detail: expect.objectContaining({ log: "[Bash] ls" }), + }), + }), + ); + }); + it("uses Claude's native agent name for the provider subagent title", () => { const tracker = new ClaudeSidechainTracker({ getToolInput: () => ({ diff --git a/packages/server/src/server/agent/providers/claude/sidechain-tracker.ts b/packages/server/src/server/agent/providers/claude/sidechain-tracker.ts index f054523126..083b82cea6 100644 --- a/packages/server/src/server/agent/providers/claude/sidechain-tracker.ts +++ b/packages/server/src/server/agent/providers/claude/sidechain-tracker.ts @@ -199,7 +199,7 @@ export class ClaudeSidechainTracker { finishAll(status: "completed" | "failed" | "canceled"): AgentStreamEvent[] { const events: AgentStreamEvent[] = []; if (this.isDescriptorOwnedElsewhere()) { - this.activeSidechains.clear(); + // The task protocol owns child completion; the parent finishing does not end its children. return events; } for (const [id, state] of this.activeSidechains) { diff --git a/packages/server/src/server/agent/providers/codex-app-server-agent.test.ts b/packages/server/src/server/agent/providers/codex-app-server-agent.test.ts index 8238a80131..8fca5f24c0 100644 --- a/packages/server/src/server/agent/providers/codex-app-server-agent.test.ts +++ b/packages/server/src/server/agent/providers/codex-app-server-agent.test.ts @@ -9,6 +9,7 @@ import { PassThrough } from "node:stream"; import { fileURLToPath } from "node:url"; import type { + AgentClient, AgentLaunchContext, AgentPermissionRequest, AgentSession, @@ -94,6 +95,7 @@ import { } from "./codex/test-utils/fake-app-server.js"; import { createTestLogger } from "../../../test-utils/test-logger.js"; import { asInternals as castInternals, createStub } from "../../test-utils/class-mocks.js"; +import { AgentManager } from "../agent-manager.js"; import { buildProviderRegistry } from "../provider-registry.js"; interface CollaborationModeRecord { @@ -7073,3 +7075,95 @@ describe("Codex denied plan approvals", () => { }); }); }); + +describe("Codex interactive resume startup", () => { + test("delivers an autonomous turn that starts during resume to the first subscriber", async () => { + const appServer = createFakeCodexAppServer({ + "turn/interrupt": () => ({}), + "thread/resume": () => { + appServer.startsTurn({ threadId: "saved-thread", turnId: "autonomous-turn" }); + appServer.says({ threadId: "saved-thread", text: "Working on the goal" }); + return { thread: { id: "saved-thread" } }; + }, + "thread/read": () => ({ thread: { turns: [] } }), + }); + const session = new CodexAppServerAgentSession( + createConfig({ modeId: "full-access" }), + { sessionId: "saved-thread" }, + createTestLogger(), + async () => appServer.child, + ); + try { + await session.connect(); + const events: AgentStreamEvent[] = []; + const unsubscribe = session.subscribe((event) => events.push(event)); + expect(events.some((event) => event.type === "turn_started")).toBe(true); + expect( + events.some( + (event) => + event.type === "timeline" && + event.item.type === "assistant_message" && + event.item.text.includes("Working on the goal"), + ), + ).toBe(true); + await session.interrupt(); + expect( + appServer.requests().find((request) => request.method === "turn/interrupt"), + ).toMatchObject({ params: { threadId: "saved-thread", turnId: "autonomous-turn" } }); + unsubscribe(); + const laterEvents: AgentStreamEvent[] = []; + session.subscribe((event) => laterEvents.push(event)); + expect(laterEvents).toEqual([]); + } finally { + await session.close(); + appServer.assertNoErrors(); + } + }); + test.each([false, true])( + "applies resumed goal events before returning (completed during resume: %s)", + async (completedDuringResume) => { + const appServer = createFakeCodexAppServer({ + "thread/resume": () => { + appServer.startsTurn({ threadId: "saved-thread", turnId: "autonomous-turn" }); + if (completedDuringResume) appServer.completeTurn({ threadId: "saved-thread" }); + return { thread: { id: "saved-thread" } }; + }, + "thread/read": () => ({ thread: { turns: [] } }), + }); + const session = new CodexAppServerAgentSession( + createConfig({ title: "Resumed goal", cwd: process.cwd() }), + { sessionId: "saved-thread" }, + createTestLogger(), + async () => appServer.child, + ); + const client: AgentClient = { + provider: "codex", + capabilities: session.capabilities, + isAvailable: async () => true, + fetchCatalog: async () => ({ models: [], modes: [] }), + createSession: async () => { + throw new Error("Unexpected create"); + }, + resumeSession: async () => { + await session.connect(); + return session; + }, + }; + const manager = new AgentManager({ clients: { codex: client }, logger: createTestLogger() }); + let id: string | undefined; + try { + const resumed = await manager.resumeAgentFromPersistence( + { provider: "codex", sessionId: "saved-thread" }, + createConfig({ title: "Resumed goal", cwd: process.cwd() }), + ); + id = resumed.id; + expect(resumed.lifecycle).toBe(completedDuringResume ? "idle" : "running"); + expect(manager.getAgent(id)?.lifecycle).toBe(completedDuringResume ? "idle" : "running"); + } finally { + if (id) await manager.closeAgent(id); + await session.close(); + appServer.assertNoErrors(); + } + }, + ); +}); diff --git a/packages/server/src/server/agent/providers/codex-app-server-agent.ts b/packages/server/src/server/agent/providers/codex-app-server-agent.ts index 36267592f8..62ceb14c70 100644 --- a/packages/server/src/server/agent/providers/codex-app-server-agent.ts +++ b/packages/server/src/server/agent/providers/codex-app-server-agent.ts @@ -3453,6 +3453,7 @@ export class CodexAppServerAgentSession implements AgentSession { private client: CodexAppServerClient | null = null; private threadRollbackAvailable = true; private readonly subscribers = new Set<(event: AgentStreamEvent) => void>(); + private startupEvents: AgentStreamEvent[] | null = null; private nextTurnOrdinal = 0; private activeForegroundTurnId: string | null = null; private activeClientMessageId: string | null = null; @@ -3571,6 +3572,8 @@ export class CodexAppServerAgentSession implements AgentSession { if (this.resumeHandle?.sessionId) { this.currentThreadId = this.resumeHandle.sessionId; this.historyPending = true; + // Resuming can start a goal before the caller receives the session. + if (this.initialResumePurpose === "interactive") this.startupEvents = []; } } @@ -4543,6 +4546,9 @@ export class CodexAppServerAgentSession implements AgentSession { subscribe(callback: (event: AgentStreamEvent) => void): () => void { this.subscribers.add(callback); + const startupEvents = this.startupEvents; + this.startupEvents = null; + for (const event of startupEvents ?? []) this.notifySubscribers(event); return () => { this.subscribers.delete(callback); }; @@ -5028,6 +5034,7 @@ export class CodexAppServerAgentSession implements AgentSession { this.clearPendingPermissions(); this.pendingSubAgentNotificationsByThreadId.clear(); this.subscribers.clear(); + this.startupEvents = null; this.activeForegroundTurnId = null; this.activeClientMessageId = null; this.pendingForegroundTurnIdentification?.resolve(null); @@ -5375,6 +5382,10 @@ export class CodexAppServerAgentSession implements AgentSession { private notifySubscribers(event: AgentStreamEvent): void { const turnId = getAgentStreamEventTurnId(event) ?? this.activeForegroundTurnId; const tagged = turnId ? { ...event, turnId } : event; + if (this.startupEvents) { + this.startupEvents.push(tagged); + return; + } this.logger.trace( { agentId: this.agentId, diff --git a/packages/server/src/server/agent/providers/omp/mcp-bridge.test.ts b/packages/server/src/server/agent/providers/omp/mcp-bridge.test.ts index 20cab26fd5..db6454edd3 100644 --- a/packages/server/src/server/agent/providers/omp/mcp-bridge.test.ts +++ b/packages/server/src/server/agent/providers/omp/mcp-bridge.test.ts @@ -285,10 +285,15 @@ describe("OMP MCP host tools", () => { expect(omp.registeredHostTools().at(-1)?.[0]?.name).toMatch(/^mcp_local__echo_secret/); omp.processExit("crashed"); await omp.startTurn("again"); - await vi.waitFor(() => { - expect(omp.runtimeSessions()).toHaveLength(2); - expect(omp.registeredHostTools().at(-1)?.[0]?.name).toMatch(/^mcp_local__echo_secret/); - }); + // The relaunch spawns a new runtime and MCP child; on a loaded Windows + // runner that has taken longer than vi.waitFor's default one second. + await vi.waitFor( + () => { + expect(omp.runtimeSessions()).toHaveLength(2); + expect(omp.registeredHostTools().at(-1)?.[0]?.name).toMatch(/^mcp_local__echo_secret/); + }, + { timeout: 10_000 }, + ); } finally { await omp.close(); } diff --git a/packages/server/src/server/agent/tools/paseo-tools.ts b/packages/server/src/server/agent/tools/paseo-tools.ts index 64d36d3b52..34a8d5ebeb 100644 --- a/packages/server/src/server/agent/tools/paseo-tools.ts +++ b/packages/server/src/server/agent/tools/paseo-tools.ts @@ -39,6 +39,8 @@ import type { FirstAgentContext } from "../../messages.js"; import { everyMsToFiveFieldCron } from "@getpaseo/protocol/schedule/cadence"; import { expandUserPath, isSameOrDescendantPath, resolvePathFromBase } from "../../path-utils.js"; import type { TerminalManager } from "../../../terminal/terminal-manager.js"; +import { encodeTerminalKeyInput } from "@getpaseo/protocol/terminal-key-input"; +import { TerminalInputModeTracker } from "@getpaseo/protocol/terminal-input-mode"; import type { CreatePaseoWorktreeWorkflowFn } from "../../worktree-session.js"; import { computeNextRunAt, validateScheduleCadence } from "../../schedule/cron.js"; import { @@ -594,37 +596,44 @@ const TerminalSummarySchema = z.object({ cwd: z.string(), }); -function resolveTerminalKeyToken(key: string, literal: boolean): string { +interface TerminalKeyTokenInput { + key: string; + literal: boolean; + preamble: string; +} + +function resolveTerminalKeyToken({ key, literal, preamble }: TerminalKeyTokenInput): string { if (literal) { return key; } - switch (key) { - case "Enter": - return "\r"; - case "Tab": - return "\t"; - case "Escape": - return "\u001b"; - case "Space": - return " "; - case "BSpace": - return "\u007f"; - case "C-c": - return "\u0003"; - case "C-d": - return "\u0004"; - case "C-z": - return "\u001a"; - case "C-l": - return "\u000c"; - case "C-a": - return "\u0001"; - case "C-e": - return "\u0005"; - default: - return key; + const match = /^((?:[CMS]-)*)(.+)$/.exec(key); + if (!match) { + return key; } + const [, modifiers, token] = match; + const aliases: Record = { + Up: "ArrowUp", + Down: "ArrowDown", + Left: "ArrowLeft", + Right: "ArrowRight", + BSpace: "Backspace", + Space: " ", + }; + const inputMode = new TerminalInputModeTracker(); + inputMode.feed(preamble); + const encodedKey = Object.hasOwn(aliases, token) ? aliases[token] : token; + return ( + encodeTerminalKeyInput( + { + key: encodedKey, + ctrl: modifiers.includes("C-"), + alt: modifiers.includes("M-"), + shift: modifiers.includes("S-"), + }, + { inputMode: inputMode.getState() }, + ) || key + ); } export function createPaseoToolCatalog(options: PaseoToolHostDependencies): PaseoToolCatalog { @@ -2591,7 +2600,8 @@ export function createPaseoToolCatalog(options: PaseoToolHostDependencies): Pase "send_terminal_keys", { title: "Send terminal keys", - description: "Send literal text or special key tokens to a terminal session.", + description: + "Send text or a key token: Enter, Tab, Escape, Space, BSpace, Up, Down, Left, Right, Home, End, Insert, Delete, PageUp, PageDown, or F1-F12. Combine C- (Ctrl), M- (Alt), and S- (Shift) prefixes, e.g. C-r, S-Tab, or C-M-Left. Set literal=true to send the text unchanged.", inputSchema: { terminalId: z.string(), keys: z.string(), @@ -2613,7 +2623,11 @@ export function createPaseoToolCatalog(options: PaseoToolHostDependencies): Pase terminal.send({ type: "input", - data: resolveTerminalKeyToken(keys, literal), + data: resolveTerminalKeyToken({ + key: keys, + literal, + preamble: terminal.getReplayPreamble(), + }), }); return { diff --git a/packages/server/src/server/authorization/operation-permissions.ts b/packages/server/src/server/authorization/operation-permissions.ts index e7e77bc0d3..0893abe1a3 100644 --- a/packages/server/src/server/authorization/operation-permissions.ts +++ b/packages/server/src/server/authorization/operation-permissions.ts @@ -210,6 +210,7 @@ const INBOUND_PERMISSION = { "workspace.script.stop.request": "workspace.write", "workspace.title.set.request": ["workspace.manage", "hub.execute"], workspace_setup_status_request: "workspace.read", + "workspace.setup.subscribe.request": "workspace.read", "workspace.setup.run.request": "workspace.write", write_project_config_request: "workspace.write", } as const satisfies Record; @@ -436,6 +437,7 @@ const OUTBOUND_PERMISSION = { "workspace.title.set.response": ["workspace.manage", "hub.execute"], workspace_setup_progress: "workspace.read", workspace_setup_status_response: "workspace.read", + "workspace.setup.subscribe.response": "workspace.read", "workspace.setup.run.response": "workspace.write", workspace_update: ["workspace.read", "hub.execute"], write_project_config_response: "workspace.write", diff --git a/packages/server/src/server/daemon-e2e/background-subagent-action-log.real.e2e.test.ts b/packages/server/src/server/daemon-e2e/background-subagent-action-log.real.e2e.test.ts new file mode 100644 index 0000000000..7eba32f22a --- /dev/null +++ b/packages/server/src/server/daemon-e2e/background-subagent-action-log.real.e2e.test.ts @@ -0,0 +1,105 @@ +import { execFile } from "node:child_process"; +import { promisify } from "node:util"; +import { fileURLToPath } from "node:url"; +import { mkdtempSync, rmSync } from "node:fs"; +import { tmpdir } from "node:os"; +import path from "node:path"; +import pino from "pino"; +import { expect, test } from "vitest"; +import { ClaudeAgentClient } from "../agent/providers/claude/agent.js"; +import { createTestPaseoDaemon } from "../test-utils/paseo-daemon.js"; +import { DaemonClient } from "../test-utils/daemon-client.js"; + +test("background cards retain child actions after the parent finishes (#6253)", async () => { + const cwd = mkdtempSync(path.join(tmpdir(), "paseo-background-card-")); + const logger = pino({ level: "silent" }); + const daemon = await createTestPaseoDaemon({ + logger, + agentClients: { claude: new ClaudeAgentClient({ logger }) }, + }); + const client = new DaemonClient({ url: `ws://127.0.0.1:${daemon.port}/ws` }); + try { + await client.connect(); + await client.fetchAgents({ subscribe: {} }); + const agent = await client.createAgent({ + provider: "claude", + model: "haiku", + modeId: "bypassPermissions", + cwd, + title: "Background action log reproduction", + }); + await client.sendMessage( + agent.id, + 'In one message, call Agent twice with run_in_background true: first with subagent_type "general-purpose", description "List files", prompt "Run ls -1, then run sleep 20, then reply with the number of entries."; second with subagent_type "general-purpose", description "Print cwd", prompt "Run pwd, then run sleep 20, then reply with the path." After launching both, reply "launched" and end your turn immediately without waiting.', + ); + await client.waitForFinish(agent.id, 180_000); + const atFinish = await client.fetchAgentTimeline(agent.id, { + direction: "tail", + limit: 0, + projection: "projected", + }); + await expect + .poll( + async () => { + const { subagents } = await client.listProviderSubagents(agent.id); + return subagents.length === 2 && subagents.every((child) => child.status === "completed"); + }, + { timeout: 180_000, interval: 1000 }, + ) + .toBe(true); + const { subagents } = await client.listProviderSubagents(agent.id); + const children = await Promise.all( + subagents.map(async (child) => ({ + description: child.description, + timeline: await client.fetchProviderSubagentTimeline(agent.id, child.id, { + direction: "tail", + limit: 0, + }), + })), + ); + const final = await client.fetchAgentTimeline(agent.id, { + direction: "tail", + limit: 0, + projection: "projected", + }); + const { stdout } = await promisify(execFile)( + process.execPath, + [ + "--conditions=source", + "--import", + "tsx", + fileURLToPath(new URL("../../../../cli/src/index.ts", import.meta.url)), + "--host", + `127.0.0.1:${daemon.port}`, + "logs", + agent.id, + ], + { env: { ...process.env, PASEO_HOME: daemon.paseoHome }, timeout: 30_000 }, + ); + expect(stdout).toContain("[Bash] ls -1"); + expect(stdout).toContain("[Bash] pwd"); + expect( + atFinish.entries.filter( + (row) => row.item.type === "tool_call" && row.item.detail?.type === "sub_agent", + ), + ).toHaveLength(2); + const cards = final.entries + .map((row) => row.item) + .filter((item) => item.type === "tool_call" && item.detail?.type === "sub_agent"); + expect(cards).toHaveLength(2); + for (const child of children) { + expect( + child.timeline.rows.some( + (row) => row.item.type === "tool_call" && row.item.name === "Bash", + ), + ).toBe(true); + } + for (const card of cards) { + expect(card.detail?.type === "sub_agent" ? card.detail.log : "").toContain("[Bash]"); + } + } finally { + await client.close(); + await daemon.close(); + rmSync(cwd, { recursive: true, force: true }); + } +}, 420_000); diff --git a/packages/server/src/server/hub/relationship-liveness.test.ts b/packages/server/src/server/hub/relationship-liveness.test.ts new file mode 100644 index 0000000000..048ee8ff80 --- /dev/null +++ b/packages/server/src/server/hub/relationship-liveness.test.ts @@ -0,0 +1,161 @@ +import { createServer as createHttpServer } from "node:http"; +import { connect, createServer as createTcpServer, type AddressInfo, type Socket } from "node:net"; +import { mkdtemp, rm } from "node:fs/promises"; +import { tmpdir } from "node:os"; +import path from "node:path"; +import pino from "pino"; +import { expect, test, vi } from "vitest"; +import { WebSocket, WebSocketServer } from "ws"; +import { HubRelationshipController } from "./relationship-controller.js"; +import { DirectHubRelationshipRemote } from "./relationship-remote.js"; + +test("a silently lost Hub connection leaves connected state and reconnects when the path recovers", async () => { + const home = await mkdtemp(path.join(tmpdir(), "paseo-hub-liveness-")); + const hub = createHttpServer(async (request, response) => { + let body = ""; + for await (const chunk of request) body += chunk; + const enrollment = JSON.parse(body) as { daemonId: string }; + response.writeHead(200, { "content-type": "application/json" }).end( + JSON.stringify({ + daemonId: enrollment.daemonId, + permissions: ["hub.execute"], + webSocketUrl: `ws://127.0.0.1:${proxyPort}/api/daemons/socket`, + }), + ); + }); + const webSockets = new WebSocketServer({ server: hub }); + const peers = new Set(); + let connections = 0; + let pongs = 0; + webSockets.on("connection", (peer) => { + connections += 1; + peers.add(peer); + peer.on("close", () => peers.delete(peer)); + }); + await listen(hub); + const hubPort = (hub.address() as AddressInfo).port; + const streams = new Set(); + let dropped = false; + const proxy = createTcpServer((client) => { + const upstream = connect(hubPort, "127.0.0.1"); + streams.add(client); + streams.add(upstream); + client.on("data", (data) => { + if (!dropped) upstream.write(data); + }); + upstream.on("data", (data) => { + if (!dropped) client.write(data); + }); + client.on("end", () => { + if (!dropped) upstream.end(); + }); + upstream.on("end", () => { + if (!dropped) client.end(); + }); + for (const socket of [client, upstream]) { + socket.on("error", () => socket.destroy()); + socket.on("close", () => streams.delete(socket)); + } + }); + await listen(proxy); + const proxyPort = (proxy.address() as AddressInfo).port; + let retry: (() => void) | undefined; + const controller = new HubRelationshipController({ + paseoHome: home, + hostname: "test-daemon", + serverId: "server-1", + daemonPublicKey: "public-key", + logger: pino({ level: "silent" }), + remote: new DirectHubRelationshipRemote(), + clock: { + now: () => new Date(), + schedule: (_delay, task) => { + retry = task; + return { cancel: () => (retry = undefined) }; + }, + }, + attachSocket: async (socket) => { + if (!(socket instanceof WebSocket)) throw new Error("Expected a real WebSocket"); + socket.on("pong", () => (pongs += 1)); + }, + updateAttachedPermissions: () => undefined, + createExecutionAgents: () => ({ + create: async () => { + throw new Error("Unexpected agent creation"); + }, + subscribe: () => () => undefined, + invalidateAuthority: async () => undefined, + }), + }); + + try { + // Keep TCP and WebSocket I/O real; accelerate only the keepalive interval and its clock. + vi.useFakeTimers({ toFake: ["setInterval", "clearInterval", "Date"] }); + await controller.connect({ + hubUrl: `http://127.0.0.1:${proxyPort}`, + token: "test-token", + permissions: ["hub.execute"], + }); + await expect.poll(() => controller.status().state).toBe("connected"); + const connectedAt = controller.status().connectedAt; + + expect(connections).toBe(1); + + // Model the reported proxy request ending without a close reaching the daemon. + dropped = true; + for (const peer of peers) peer.terminate(); + await expect.poll(() => peers.size).toBe(0); + await vi.advanceTimersByTimeAsync(60_000); + await expect.poll(() => controller.status().state).toBe("reconnecting"); + expect(controller.status().lastError).toBe("Hub WebSocket heartbeat timed out"); + expect(retry).toBeTypeOf("function"); + + dropped = false; + retry?.(); + await expect.poll(() => controller.status().state).toBe("connected"); + expect(connections).toBe(2); + expect(controller.status().connectedAt).not.toBe(connectedAt); + expect(controller.status().lastError).toBeNull(); + + // A healthy idle connection survives multiple liveness windows. + for (let tick = 0; tick < 12; tick += 1) { + const before = pongs; + await vi.advanceTimersByTimeAsync(10_000); + await expect.poll(() => pongs).toBeGreaterThan(before); + } + expect(controller.status().state).toBe("connected"); + expect(connections).toBe(2); + + await controller.stop(); + await expect.poll(() => peers.size).toBe(0); + await expect.poll(() => vi.getTimerCount()).toBe(0); + } finally { + await controller.stop(); + vi.useRealTimers(); + for (const socket of streams) socket.destroy(); + for (const peer of peers) peer.terminate(); + webSockets.close(); + await Promise.all([close(proxy), close(hub)]); + await rm(home, { recursive: true, force: true }); + } +}); + +async function listen( + server: ReturnType | ReturnType, +) { + await new Promise((resolve) => server.listen(0, "127.0.0.1", resolve)); +} + +async function close( + server: ReturnType | ReturnType, +) { + await new Promise((resolve, reject) => { + server.close((error) => { + if (error) { + reject(error); + return; + } + resolve(); + }); + }); +} diff --git a/packages/server/src/server/hub/relationship-remote.ts b/packages/server/src/server/hub/relationship-remote.ts index d0ae01089d..9c6f88a63d 100644 --- a/packages/server/src/server/hub/relationship-remote.ts +++ b/packages/server/src/server/hub/relationship-remote.ts @@ -2,6 +2,9 @@ import { WebSocket } from "ws"; import { z } from "zod"; import type { WebSocketLike } from "../websocket-server.js"; +const SOCKET_PING_INTERVAL_MS = 10_000; +const SOCKET_PONG_TIMEOUT_MS = 45_000; + export interface HubEnrollment { daemonId: string; idempotencyKey: string; @@ -171,13 +174,42 @@ export class DirectHubRelationshipRemote implements HubRelationshipRemote { }, }); let settled = false; + let heartbeat: ReturnType | undefined; + const stopHeartbeat = () => { + clearInterval(heartbeat); + heartbeat = undefined; + }; + const fail = (error: Error) => { + if (settled) return; + settled = true; + stopHeartbeat(); + socket.terminate(); + events.failed(error); + }; + let lastPongAt = 0; + socket.on("pong", () => { + lastPongAt = Date.now(); + }); socket.once("upgrade", (response) => { if (response.headers["x-paseo-session-protocol"] === "1") { sessionProtocol = "session-v1"; } }); socket.once("open", () => { - if (!settled) events.connected(socket as WebSocketLike, sessionProtocol); + if (settled) return; + lastPongAt = Date.now(); + heartbeat = setInterval(() => { + if (socket.readyState !== WebSocket.OPEN) return; + if (Date.now() - lastPongAt >= SOCKET_PONG_TIMEOUT_MS) { + fail(new Error("Hub WebSocket heartbeat timed out")); + return; + } + socket.ping(undefined, undefined, (error) => { + if (error) fail(error); + }); + }, SOCKET_PING_INTERVAL_MS); + heartbeat.unref?.(); + events.connected(socket as WebSocketLike, sessionProtocol); }); socket.once("unexpected-response", (_request, response) => { if (settled) { @@ -194,16 +226,12 @@ export class DirectHubRelationshipRemote implements HubRelationshipRemote { events.closed(1006); }); socket.once("close", (code) => { + stopHeartbeat(); if (settled) return; settled = true; events.closed(code); }); - socket.once("error", (error) => { - if (settled) return; - settled = true; - socket.terminate(); - events.failed(error); - }); + socket.once("error", fail); return socket; } diff --git a/packages/server/src/server/plugins/compiler.test.ts b/packages/server/src/server/plugins/compiler.test.ts index 0ddf97b6f3..231639ec96 100644 --- a/packages/server/src/server/plugins/compiler.test.ts +++ b/packages/server/src/server/plugins/compiler.test.ts @@ -574,6 +574,25 @@ export type Value = string;`, expect(clientBundle).not.toContain("React.createElement"); }); + it("imports an SVG file from a runtime directory as its markup", async () => { + const entries = await createSplitPlugin(); + const svg = ''; + await writeFile(path.join(entries.directory, "client", "icon.svg"), svg); + await writeFile( + entries.client, + `import icon from "./client/icon.svg"; +export default function contribute(client) { + client.addCommandCenterItem({ id: "open", title: "Open", icon: { svg: icon }, context: "global", onSelect() {} }); + return () => undefined; +}`, + ); + const { clientBundle } = await compilePlugin(entries); + const registered: unknown[] = []; + const exports = new Function(`return ${clientBundle}`)()(() => undefined); + exports.default({ addCommandCenterItem: (item: unknown) => registered.push(item) }); + expect(registered).toMatchObject([{ icon: { svg } }]); + }); + it("lowers async callbacks before Hermes evaluates the client bundle", async () => { const entries = await createSplitPlugin(); await writeFile( diff --git a/packages/server/src/server/plugins/compiler.ts b/packages/server/src/server/plugins/compiler.ts index 5cdce3ad6c..4567921082 100644 --- a/packages/server/src/server/plugins/compiler.ts +++ b/packages/server/src/server/plugins/compiler.ts @@ -401,6 +401,8 @@ async function compileTarget(entryPath: string, target: PluginBuildTarget): Prom bundle: true, format: "cjs", jsx: "automatic", + // `import icon from "./icon.svg"` yields the markup for an inline `{ svg }` icon. + loader: { ".svg": "text" }, platform: target === "server" ? "node" : "neutral", target: target === "server" ? "node20" : "es2020", // The neutral platform reads no package.json entry fields, so packages without diff --git a/packages/server/src/server/plugins/provider-icon.test.ts b/packages/server/src/server/plugins/provider-icon.test.ts index 4faf9d289c..f8040ec869 100644 --- a/packages/server/src/server/plugins/provider-icon.test.ts +++ b/packages/server/src/server/plugins/provider-icon.test.ts @@ -29,18 +29,14 @@ describe("readPluginProviderIcon", () => { }); test.each([ - ["non-SVG document", "hello", "file is not an SVG document"], - ["script", "", "script elements"], - ["foreign object", "", "foreignObject elements"], - ["style", "", "style elements"], - ["event handler", '', "event-handler attributes"], - ["javascript URL", '', "javascript URLs"], + ["non-SVG document", "hello", "not an SVG document"], + ["script", "", "script elements are not allowed"], ["external href", '', "external href"], - ])("rejects %s", async (_name, svg, reason) => { + ])("rejects %s with the shared SVG rules", async (_name, svg, reason) => { const directory = await writeIcon(svg); await expect(readPluginProviderIcon(directory, "icon.svg")).rejects.toThrow( - `icon.svg": ${reason}`, + `Invalid plugin provider icon "icon.svg": ${reason}`, ); }); @@ -78,7 +74,7 @@ describe("readPluginProviderIcon", () => { const directory = await writeIcon(`${" ".repeat(64 * 1024)}`); await expect(readPluginProviderIcon(directory, "icon.svg")).rejects.toThrow( - "file exceeds 64 KiB", + `Invalid plugin provider icon "icon.svg": exceeds 64 KiB`, ); }); }); diff --git a/packages/server/src/server/plugins/provider-icon.ts b/packages/server/src/server/plugins/provider-icon.ts index 9a1e3f6714..af33ea82f5 100644 --- a/packages/server/src/server/plugins/provider-icon.ts +++ b/packages/server/src/server/plugins/provider-icon.ts @@ -1,7 +1,6 @@ import { readFile, realpath, stat } from "node:fs/promises"; import path from "node:path"; - -const MAX_ICON_BYTES = 64 * 1024; +import { findSvgIconProblem } from "@getpaseo/plugin"; export async function readPluginProviderIcon( pluginDirectory: string, @@ -20,10 +19,10 @@ export async function readPluginProviderIcon( if (!iconStat.isFile()) { throw iconError(iconPath, "file does not exist or is not a regular file"); } - if (iconStat.size > MAX_ICON_BYTES) throw iconError(iconPath, "file exceeds 64 KiB"); const svg = await readFile(resolvedIcon, "utf8"); - validateSvg(iconPath, svg); + const problem = findSvgIconProblem(svg); + if (problem) throw iconError(iconPath, problem); return svg; } @@ -38,27 +37,6 @@ function assertInsidePluginDirectory( if (escapesDirectory) throw iconError(iconPath, "path leaves the plugin directory"); } -function validateSvg(iconPath: string, svg: string): void { - if (!/^\s*)/i.test(svg)) throw iconError(iconPath, "file is not an SVG document"); - if (/)/i.test(svg)) throw iconError(iconPath, "script elements are not allowed"); - if (/)/i.test(svg)) { - throw iconError(iconPath, "foreignObject elements are not allowed"); - } - if (/)/i.test(svg)) throw iconError(iconPath, "style elements are not allowed"); - if (/\son[a-z0-9_-]*\s*=/i.test(svg)) { - throw iconError(iconPath, "event-handler attributes are not allowed"); - } - if (/javascript\s*:/i.test(svg)) throw iconError(iconPath, "javascript URLs are not allowed"); - - const hrefPattern = /\s(?:href|xlink:href)\s*=\s*(?:(["'])(.*?)\1|([^\s>]+))/gi; - for (const match of svg.matchAll(hrefPattern)) { - const href = match[2] ?? match[3] ?? ""; - if (!href.startsWith("#")) { - throw iconError(iconPath, "external href references are not allowed"); - } - } -} - function iconError(iconPath: string, reason: string): Error { return new Error(`Invalid plugin provider icon "${iconPath}": ${reason}`); } diff --git a/packages/server/src/server/plugins/usage-sources/index.test.ts b/packages/server/src/server/plugins/usage-sources/index.test.ts index eeea242788..da9d52eaeb 100644 --- a/packages/server/src/server/plugins/usage-sources/index.test.ts +++ b/packages/server/src/server/plugins/usage-sources/index.test.ts @@ -1,5 +1,72 @@ import { expect, test } from "vitest"; import { UsageSourceRegistry } from "./index.js"; +import { mkdtemp, mkdir, writeFile, rm } from "node:fs/promises"; +import { tmpdir } from "node:os"; +import { join } from "node:path"; +import { + discoverSession as discoverCursorSession, + fetchUsage as fetchCursorUsage, +} from "../../../../../../plugins/cursor-usage-source/server/usage.js"; +import { inputSchema as cursorInputSchema } from "../../../../../../plugins/cursor-usage-source/shared/input.js"; + +test("#7142: host usage retains distinct Cursor accounts after their individual details are read", async () => { + const root = await mkdtemp(join(tmpdir(), "cursor-accounts-")); + try { + const sessions = new Map< + string, + { provider: string; sessionKey: string; env: Record } + >(); + const spends = new Map(); + for (const [agentId, account, spend] of [ + ["a", "user-a", 100], + ["b", "user-b", 200], + ["a-copy", "user-a", 100], + ] as const) { + const configHome = join(root, agentId); + const token = `e30.${Buffer.from(JSON.stringify({ sub: account, nonce: agentId })).toString("base64url")}.signature`; + await mkdir(join(configHome, "cursor"), { recursive: true }); + await writeFile( + join(configHome, "cursor", "auth.json"), + JSON.stringify({ accessToken: token }), + ); + spends.set(`Bearer ${token}`, spend); + sessions.set(agentId, { + provider: "cursor", + sessionKey: agentId, + env: { XDG_CONFIG_HOME: configHome }, + }); + } + const registry = new UsageSourceRegistry(Date.now, 300_000, undefined, { + hasAgent: (id) => sessions.has(id), + usageSession: (id) => sessions.get(id) ?? null, + }); + const fetchApi: typeof fetch = async (_url, init) => { + const authorization = new Headers(init?.headers).get("Authorization") ?? ""; + const spend = spends.get(authorization); + if (spend === undefined) throw new Error("Unexpected fixture login"); + return new Response(JSON.stringify({ planUsage: { totalSpend: spend, limit: 1000 } })); + }; + registry.register({ + id: "cursor", + label: "Cursor", + discover: (scope) => + scope.kind === "session" ? discoverCursorSession(scope, "linux") : Promise.resolve([]), + fetch: (input) => fetchCursorUsage(cursorInputSchema.parse(input), fetchApi), + }); + const spent = (reports: Awaited>) => + reports.map((entry) => { + if (entry.report.status !== "available") + throw new Error("Expected available fixture usage"); + return entry.report.balances?.[0]?.used; + }); + expect(spent(await registry.listReports({ agentId: "a" }))).toEqual([1]); + expect(spent(await registry.listReports({ agentId: "b" }))).toEqual([2]); + expect(spent(await registry.listReports({ agentId: "a-copy" }))).toEqual([1]); + expect(spent(await registry.listReports())).toEqual([1, 2]); + } finally { + await rm(root, { recursive: true, force: true }); + } +}); function source(input: { id: string; @@ -556,3 +623,208 @@ test("a hung login records its own timeout and still tries the next login", asyn { harness: "OpenCode", report: { status: "error", error: "Login rejected" } }, ]); }); + +test("retains the last successful poll across failures, cache expiry, and recovery", async () => { + let now = 0; + let report: unknown = { + status: "available", + windows: [{ id: "week", label: "Weekly", usedPct: 42 }], + }; + const registry = new UsageSourceRegistry(() => now); + registry.register( + source({ + id: "quota", + discover: async () => [{ key: "account", input: {} }], + fetch: async () => report, + }), + ); + registry.register(source({ id: "other", discover: async () => [{ key: "account", input: {} }] })); + const [success] = await registry.listReports(); + now = 360_000; + // An unrelated write evicts the expired fetch result, but must not discard its snapshot. + await registry.listReports({ reportIds: ["other:account"], forceRefresh: true }); + report = { status: "error", error: "Rate limited" }; + const [failure] = await registry.listReports({ reportIds: ["quota:account"] }); + expect(failure).toMatchObject({ + fetchedAt: new Date(now).toISOString(), + report, + lastSuccessful: { fetchedAt: success!.fetchedAt, report: success!.report }, + }); + now += 360_000; + const [repeated] = await registry.listReports({ reportIds: ["quota:account"] }); + expect(repeated?.lastSuccessful).toEqual(failure?.lastSuccessful); + report = { status: "unavailable", problem: { kind: "no_quota", detail: "No quota" } }; + const [unavailable] = await registry.listReports({ + reportIds: ["quota:account"], + forceRefresh: true, + }); + expect(unavailable?.lastSuccessful).toEqual(failure?.lastSuccessful); + now += 1000; + report = { status: "available", windows: [{ id: "week", label: "Weekly", usedPct: 43 }] }; + const [recovered] = await registry.listReports({ + reportIds: ["quota:account"], + forceRefresh: true, + }); + expect(recovered?.report).toEqual(report); + expect(recovered?.lastSuccessful).toBeUndefined(); + expect(recovered?.fetchedAt).toBe(new Date(now).toISOString()); +}); + +test("successful history is isolated by login set and pruned when identities retire", async () => { + let login = "old"; + let present = true; + let available = true; + const registry = new UsageSourceRegistry(); + const fixture = source({ + id: "source", + discover: async () => (present ? [{ key: "same", input: login }] : []), + fetch: async () => + available ? { status: "available", windows: [] } : { status: "error", error: "failed" }, + }); + registry.register(fixture); + await registry.listReports(); + available = false; + login = "new"; + expect((await registry.listReports({ forceRefresh: true }))[0]?.lastSuccessful).toBeUndefined(); + login = "old"; + expect((await registry.listReports({ forceRefresh: true }))[0]?.lastSuccessful).toBeUndefined(); + available = true; + await registry.listReports({ forceRefresh: true }); + present = false; + expect(await registry.listReports()).toEqual([]); + present = true; + available = false; + expect((await registry.listReports())[0]?.lastSuccessful).toBeUndefined(); + available = true; + await registry.listReports({ forceRefresh: true }); + registry.unregister("source"); + registry.register(fixture); + available = false; + expect((await registry.listReports())[0]?.lastSuccessful).toBeUndefined(); +}); + +test("host fallback history never supplies an agent's failed login, and removed agents lose history", async () => { + const sessions = new Map([["agent", { provider: "codex", env: {}, sessionKey: "one" }]]); + let available = true; + const registry = new UsageSourceRegistry(Date.now, 300_000, undefined, { + hasAgent: (id) => sessions.has(id), + usageSession: (id) => sessions.get(id) ?? null, + }); + registry.register({ + id: "source", + label: "Source", + discover: async (scope) => + (scope.kind === "global" ? ["host", "agent"] : ["agent"]).map((input) => ({ + key: "same", + input, + })), + fetch: async () => + available ? { status: "available", windows: [] } : { status: "error", error: "failed" }, + }); + await registry.listReports(); + available = false; + expect((await registry.listReports({ agentId: "agent" }))[0]?.lastSuccessful).toBeUndefined(); + available = true; + const [success] = await registry.listReports({ agentId: "agent", forceRefresh: true }); + available = false; + expect( + (await registry.listReports({ agentId: "agent", forceRefresh: true }))[0]?.lastSuccessful + ?.report, + ).toEqual(success?.report); + sessions.delete("agent"); + await registry.listReports(); + sessions.set("agent", { provider: "codex", env: {}, sessionKey: "two" }); + expect((await registry.listReports({ agentId: "agent" }))[0]?.lastSuccessful).toBeUndefined(); +}); + +test("a timed out poll retains successful values and late completion cannot replace the failure", async () => { + let now = 1000; + let finish!: (value: unknown) => void; + let slow = false; + const registry = new UsageSourceRegistry(() => now, 300_000, undefined, undefined, 10); + registry.register( + source({ + id: "source", + discover: async () => [{ key: "same", input: {} }], + fetch: async () => + slow + ? new Promise((resolve) => { + finish = resolve; + }) + : { status: "available", windows: [] }, + }), + ); + const [success] = await registry.listReports(); + now = 2000; + slow = true; + const [failure] = await registry.listReports({ forceRefresh: true }); + expect(failure?.report).toEqual({ status: "error", error: "Usage fetch timed out" }); + expect(failure?.lastSuccessful).toEqual({ + fetchedAt: success?.fetchedAt, + report: success?.report, + }); + finish({ status: "available", windows: [{ id: "late", label: "Late" }] }); + expect((await registry.listReports())[0]).toEqual(failure); +}); + +test("attempt ordering keeps its timestamp while retained freshness records successful completion", async () => { + let now = 1000; + let available = true; + const registry = new UsageSourceRegistry(() => now); + registry.register( + source({ + id: "source", + discover: async () => [{ key: "same", input: {} }], + fetch: async () => { + if (available) now = 2000; + return available + ? { status: "available", windows: [] } + : { status: "error", error: "failed" }; + }, + }), + ); + const [success] = await registry.listReports(); + expect(success?.fetchedAt).toBe(new Date(1000).toISOString()); + expect(success?.successfulAt).toBe(new Date(2000).toISOString()); + available = false; + now = 3000; + const [failure] = await registry.listReports({ forceRefresh: true }); + expect(failure?.fetchedAt).toBe(new Date(3000).toISOString()); + expect(failure?.lastSuccessful?.fetchedAt).toBe(success?.successfulAt); +}); + +test("failed discovery preserves history until discovery confirms account removal", async () => { + let discoveryFails = false; + let present = true; + let available = true; + const registry = new UsageSourceRegistry(() => 1000, 300_000, { warn: () => {} }); + registry.register( + source({ + id: "source", + discover: async () => { + if (discoveryFails) throw new Error("Login store temporarily unavailable"); + return present ? [{ key: "account", input: {} }] : []; + }, + fetch: async () => + available + ? { status: "available", windows: [{ id: "weekly", label: "Weekly", usedPct: 42 }] } + : { status: "error", error: "Rate limited" }, + }), + ); + const [success] = await registry.listReports(); + available = false; + discoveryFails = true; + const [duringDiscoveryFailure] = await registry.listReports({ forceRefresh: true }); + expect(duringDiscoveryFailure?.lastSuccessful).toEqual({ + fetchedAt: success?.successfulAt, + report: success?.report, + }); + discoveryFails = false; + const [afterDiscoveryRecovery] = await registry.listReports({ forceRefresh: true }); + expect(afterDiscoveryRecovery?.lastSuccessful).toEqual(duringDiscoveryFailure?.lastSuccessful); + expect(afterDiscoveryRecovery?.report).toEqual({ status: "error", error: "Rate limited" }); + present = false; + expect(await registry.listReports()).toEqual([]); + present = true; + expect((await registry.listReports())[0]?.lastSuccessful).toBeUndefined(); +}); diff --git a/packages/server/src/server/plugins/usage-sources/index.ts b/packages/server/src/server/plugins/usage-sources/index.ts index c0c9d781e5..e9e2e9c8af 100644 --- a/packages/server/src/server/plugins/usage-sources/index.ts +++ b/packages/server/src/server/plugins/usage-sources/index.ts @@ -56,6 +56,7 @@ export class UsageSourceRegistry { private defaults = new Map(); private readonly byAgent = new Map(); private readonly cache = new Map(); + private readonly successful = new Map>(); private readonly pending = new Map>(); constructor( @@ -81,6 +82,8 @@ export class UsageSourceRegistry { } for (const key of this.known.keys()) if (key.startsWith(`${id}:`)) this.known.delete(key); for (const key of this.cache.keys()) if (key.startsWith(`${id}:`)) this.cache.delete(key); + for (const key of this.successful.keys()) + if (key.startsWith(`${id}:`)) this.successful.delete(key); for (const key of this.pending.keys()) if (key.startsWith(`${id}:`)) this.pending.delete(key); } @@ -96,7 +99,7 @@ export class UsageSourceRegistry { } else if (options.reportIds !== undefined) { ids = options.reportIds; } else { - this.defaults = await this.discover({ kind: "global" }); + this.defaults = await this.discover({ kind: "global" }, this.defaults); this.mergeKnown(); ids = [...this.known.keys()]; } @@ -124,7 +127,11 @@ export class UsageSourceRegistry { private async discoverAgent(agentId: string): Promise { if (!this.agents.hasAgent(agentId)) throw new Error(`Unknown agent: ${agentId}`); const session = this.agents.usageSession(agentId); - if (!session) return []; + if (!session) { + this.byAgent.delete(agentId); + this.mergeKnown(); + return []; + } const previous = this.byAgent.get(agentId); const sameScope = previous?.sessionKey === session.sessionKey && @@ -168,9 +175,26 @@ export class UsageSourceRegistry { } } } + // Fetch freshness expires independently of successful snapshots. Retain only live identities. + const active = this.activeCacheKeys(); + for (const key of this.successful.keys()) if (!active.has(key)) this.successful.delete(key); + for (const key of this.cache.keys()) if (!active.has(key)) this.cache.delete(key); } - private async discover(scope: UsageScope): Promise> { + private activeCacheKeys(): Set { + return new Set( + [ + this.known, + this.defaults, + ...[...this.byAgent.values()].map((agent) => agent.reports), + ].flatMap((reports) => [...reports].map(([id, report]) => cacheIdentity(id, report))), + ); + } + + private async discover( + scope: UsageScope, + previous: ReadonlyMap = new Map(), + ): Promise> { const discovered = await Promise.all( [...this.sources.values()].map(async (source) => { const reports = new Map(); @@ -197,6 +221,11 @@ export class UsageSourceRegistry { } } catch (error) { this.logger.warn({ sourceId: source.id, err: error }, "Usage source discovery failed"); + // A failed store read does not confirm removal. Session discovery has no previous + // mapping because a resumed agent may use a different launch environment. + for (const [id, report] of previous) { + if (report.source === source) reports.set(id, report); + } } return reports; }), @@ -235,25 +264,42 @@ export class UsageSourceRegistry { private fetchId(id: string, known: KnownReport, forceRefresh = false): Promise { // Account identity groups cards; the ordered login set identifies a fetch result. - const cacheKey = `${id}:${createHash("sha256") - .update(JSON.stringify([known.label, known.logins.map(loginKey)])) - .digest("hex")}`; + const cacheKey = cacheIdentity(id, known); const cached = this.cache.get(cacheKey); if (!forceRefresh && cached && this.now() - cached.at < this.ttlMs) return Promise.resolve(cached.entry); const pending = this.pending.get(cacheKey); if (pending) return pending; const request = (async () => { + const fetchedAt = new Date(this.now()).toISOString(); + const outcome = await this.fetchWithFallback(known); + const completedAt = new Date(this.now()).toISOString(); const entry: UsageReportEntry = { id, sourceId: known.source.id, sourceLabel: known.source.label, icon: known.source.icon, account: { label: known.label }, - fetchedAt: new Date(this.now()).toISOString(), - ...(await this.fetchWithFallback(known)), + fetchedAt, + ...outcome, }; - if (this.sources.get(known.source.id) === known.source) this.writeCache(cacheKey, entry); + if (entry.report.status === "available") { + entry.successfulAt = completedAt; + } else { + entry.lastSuccessful = this.successful.get(cacheKey); + } + if ( + this.sources.get(known.source.id) === known.source && + this.activeCacheKeys().has(cacheKey) + ) { + if (entry.report.status === "available") { + this.successful.set(cacheKey, { + fetchedAt: completedAt, + report: entry.report, + }); + } + this.writeCache(cacheKey, entry); + } return entry; })(); this.pending.set(cacheKey, request); @@ -346,3 +392,9 @@ function loginKey(login: Login): string { : value, ); } + +function cacheIdentity(id: string, known: KnownReport): string { + return `${id}:${createHash("sha256") + .update(JSON.stringify([known.label, known.logins.map(loginKey)])) + .digest("hex")}`; +} diff --git a/packages/server/src/server/relay-transport.latency.e2e.test.ts b/packages/server/src/server/relay-transport.latency.e2e.test.ts new file mode 100644 index 0000000000..84404da0c1 --- /dev/null +++ b/packages/server/src/server/relay-transport.latency.e2e.test.ts @@ -0,0 +1,61 @@ +import { execFile } from "node:child_process"; +import { mkdtemp, readFile, rm, writeFile } from "node:fs/promises"; +import os from "node:os"; +import path from "node:path"; +import { fileURLToPath } from "node:url"; +import { promisify } from "node:util"; +import { expect, test } from "vitest"; + +const run = promisify(execFile); + +// Opt in on Linux with passwordless sudo, unshare, ip, mount, and tc available: +// RUN_RELAY_LATENCY_E2E=1 npx vitest run src/server/relay-transport.latency.e2e.test.ts +// All networking and the hosts-file mount are private to the child namespaces. +test.runIf(process.platform === "linux" && process.env.RUN_RELAY_LATENCY_E2E === "1")( + "connects relay control and data over a slow dual-stack route with an unreachable address", + async () => { + const directory = await mkdtemp(path.join(os.tmpdir(), "paseo-relay-latency-")); + try { + const hosts = path.join(directory, "hosts"); + await writeFile( + hosts, + `${await readFile("/etc/hosts", "utf8")}\n127.0.0.1 relay-latency.test\n2001:db8:1::1 relay-latency.test\n`, + ); + const fixture = fileURLToPath( + new URL("./test-utils/relay-latency-fixture.ts", import.meta.url), + ); + for (const order of ["ipv4first", "ipv6first"]) { + const { stdout } = await run( + "sudo", + [ + "-n", + "unshare", + "--mount", + "--net", + "sh", + "-ec", + `mount --make-rprivate / +mount --bind "$1" /etc/hosts +ip link set lo up +ip link add relay-test type dummy +ip addr add 192.0.2.2/32 dev relay-test +ip -6 addr add 2001:db8::2/128 dev relay-test +ip link set relay-test up +tc qdisc add dev lo root netem delay 350ms +exec "$2" --import tsx "$3" "$4"`, + "sh", + hosts, + process.execPath, + fixture, + order, + ], + { timeout: 20_000 }, + ); + expect(stdout).toContain("relay data round trip passed"); + } + } finally { + await rm(directory, { recursive: true, force: true }); + } + }, + 45_000, +); diff --git a/packages/server/src/server/relay-transport.ts b/packages/server/src/server/relay-transport.ts index f7b73a5367..113cce605c 100644 --- a/packages/server/src/server/relay-transport.ts +++ b/packages/server/src/server/relay-transport.ts @@ -56,7 +56,13 @@ type ControlMessage = const CONTROL_PING_INTERVAL_MS = 10_000; const CONTROL_STALE_TIMEOUT_MS = 30_000; const CONTROL_READY_TIMEOUT_MS = 8_000; -const RELAY_WEBSOCKET_OPTIONS = { handshakeTimeout: 10_000, perMessageDeflate: false } as const; +const RELAY_WEBSOCKET_OPTIONS = { + handshakeTimeout: 10_000, + perMessageDeflate: false, + // Node cancels each non-final address when this expires, even if the next + // address is unreachable. Allow high-latency routes time to connect. + autoSelectFamilyAttemptTimeout: 5_000, +} as const; function createDefaultRelayWebSocket(url: string): RelayWebSocketLike { return new WebSocket(url, RELAY_WEBSOCKET_OPTIONS); diff --git a/packages/server/src/server/session.ts b/packages/server/src/server/session.ts index 08d3f0eefb..87949594aa 100644 --- a/packages/server/src/server/session.ts +++ b/packages/server/src/server/session.ts @@ -13,6 +13,7 @@ import { CreationService, type CreatedAgent } from "./creation/index.js"; import type { CreationSnapshot, AgentCreateRequest } from "@getpaseo/protocol/messages"; import type { MessageReceipts } from "./message-receipts/index.js"; import equal from "fast-deep-equal"; +import { WorkspaceSetupObservation } from "./workspace-setup-observation.js"; import { SessionDelivery, type OwnedSubscription } from "./session/owned-subscriptions/index.js"; import { v4 as uuidv4 } from "uuid"; import { lstat, mkdir, mkdtemp, rename, rm, stat } from "node:fs/promises"; @@ -531,7 +532,7 @@ export interface SessionOptions { hubRelationships?: HubRelationshipManagement; serviceProxy?: ServiceProxySubsystem; scriptRuntimeStore?: WorkspaceScriptRuntimeStore; - workspaceSetupSnapshots?: Map; + workspaceSetupObservation?: WorkspaceSetupObservation; workspaceSetupRuntime?: WorkspaceSetupRuntime; onBranchChanged?: ( workspaceId: string, @@ -783,7 +784,8 @@ export class Session { private readonly terminalController: TerminalSessionController; private inflightRequests = 0; private peakInflightRequests = 0; - private readonly workspaceSetupSnapshots: Map; + private readonly workspaceSetupObservation: WorkspaceSetupObservation; + private readonly unsubscribeSetupObservation: () => void; private readonly workspaceSetupRuntime: WorkspaceSetupRuntime; private readonly workspaceGitObserver: WorkspaceGitObserverService; private readonly workspaceDirectory: WorkspaceDirectory; @@ -844,7 +846,7 @@ export class Session { providerSnapshotManager, serviceProxy, scriptRuntimeStore, - workspaceSetupSnapshots, + workspaceSetupObservation, workspaceSetupRuntime, onBranchChanged, getDaemonTcpPort, @@ -1151,7 +1153,19 @@ export class Session { this.providerSnapshotManager = providerSnapshotManager; this.serviceProxy = serviceProxy ?? null; this.scriptRuntimeStore = scriptRuntimeStore ?? null; - this.workspaceSetupSnapshots = workspaceSetupSnapshots ?? new Map(); + this.workspaceSetupObservation = workspaceSetupObservation ?? new WorkspaceSetupObservation(); + this.unsubscribeSetupObservation = this.workspaceSetupObservation.subscribe( + (workspaceId, snapshot, statusChanged) => { + if (statusChanged) + void this.emitWorkspaceUpdateForWorkspaceId(workspaceId).catch((error) => + this.sessionLogger.warn({ err: error, workspaceId }, "Failed to publish setup status"), + ); + this.emitSubscribedEvent({ + type: "workspace_setup_progress", + payload: { workspaceId, ...snapshot }, + }); + }, + ); this.workspaceSetupRuntime = resolveWorkspaceSetupRuntime(workspaceSetupRuntime); this.getDaemonTcpPort = getDaemonTcpPort ?? null; this.getDaemonTcpHost = getDaemonTcpHost ?? null; @@ -2293,10 +2307,50 @@ export class Session { } } + private async subscribeWorkspaceSetup( + request: Extract, + ): Promise { + if ( + !this.supports(CLIENT_CAPS.workspaceSetupObservation) || + !this.delivery.isModern(this.delivery.currentSource) + ) + throw new Error("Workspace setup observation requires owned subscriptions"); + // Resolve persisted blocked state first. Register and read the current cache in one + // synchronous turn afterward, so a setup transition during this read cannot be lost. + let initial: WorkspaceSetupSnapshot | null = null; + await handleWorkspaceSetupStatusRequestMessage( + { + workspaceSetupSnapshots: this.workspaceSetupObservation, + getWorkspace: (id) => this.workspaceRegistry.get(id), + emit: (message) => { + if (message.type === "workspace_setup_status_response") + initial = message.payload.snapshot; + }, + }, + { ...request, type: "workspace_setup_status_request" }, + ); + let stop: (() => void) | undefined; + const owner = this.delivery.begin("workspace-setup", undefined, () => stop?.()); + stop = this.workspaceSetupObservation.subscribe((workspaceId, snapshot) => { + if (workspaceId === request.workspaceId) + owner.emit({ type: "workspace_setup_progress", payload: { workspaceId, ...snapshot } }); + }); + this.emit({ + type: "workspace.setup.subscribe.response", + payload: { + requestId: request.requestId, + subscriptionId: owner.responseId, + workspaceId: request.workspaceId, + snapshot: this.workspaceSetupObservation.get(request.workspaceId) ?? initial, + }, + }); + } + private dispatchSubscriptionMessage( msg: SessionInboundMessage, source?: object, ): Promise | undefined { + if (msg.type === "workspace.setup.subscribe.request") return this.subscribeWorkspaceSetup(msg); if (msg.type === "browser.host.register.request") return this.registerBrowserHost(msg); if (msg.type === "browser.automation.execute.response") { if (source) @@ -5602,6 +5656,7 @@ export class Session { projectCustomIconRevision: resolvedProjectRecord?.customIconRevision ?? null, projectRootPath: resolvedProjectRecord?.rootPath ?? workspace.cwd, workspaceDirectory: workspace.cwd, + setupStatus: this.workspaceSetupObservation.status(workspace), worktreeSlug, projectKind: (resolvedProjectRecord?.kind ?? "directory") === "git" ? "git" : "non_git", workspaceKind: workspace.kind, @@ -5692,6 +5747,7 @@ export class Session { projectCustomIconRevision: projectRecord?.customIconRevision ?? null, projectRootPath: projectRecord?.rootPath ?? result.repoRoot, workspaceDirectory: result.workspace.cwd, + setupStatus: this.workspaceSetupObservation.status(result.workspace), worktreeSlug: basename(result.worktree.worktreePath), projectKind: projectRecord?.kind ?? "git", workspaceKind: result.workspace.kind, @@ -7365,7 +7421,7 @@ export class Session { emitWorkspaceUpdateForWorkspaceId: (workspaceId) => this.emitWorkspaceUpdateForWorkspaceId(workspaceId), cacheWorkspaceSetupSnapshot: (workspaceId, snapshot) => { - this.workspaceSetupSnapshots.set(workspaceId, snapshot); + this.workspaceSetupObservation.cache(workspaceId, snapshot); }, emit: (message) => this.emit(message), sessionLogger: this.sessionLogger, @@ -7390,7 +7446,7 @@ export class Session { return handleWorkspaceSetupStatusRequestMessage( { emit: (message) => this.emit(message), - workspaceSetupSnapshots: this.workspaceSetupSnapshots, + workspaceSetupSnapshots: this.workspaceSetupObservation, getWorkspace: (workspaceId) => this.workspaceRegistry.get(workspaceId), }, request, @@ -7412,7 +7468,7 @@ export class Session { emitWorkspaceUpdateForWorkspaceId: (workspaceId) => this.emitWorkspaceUpdateForWorkspaceId(workspaceId), cacheWorkspaceSetupSnapshot: (workspaceId, snapshot) => - this.workspaceSetupSnapshots.set(workspaceId, snapshot), + this.workspaceSetupObservation.cache(workspaceId, snapshot), emit: (message) => this.emit(message), sessionLogger: this.sessionLogger, terminalManager: this.terminalManager, @@ -8392,8 +8448,22 @@ export class Session { */ // COMPAT(explicitEventSubscriptions): added in v0.8.0, remove legacy broadcasts after 2027-03-08. private wantsEvent(event: SessionEventSubscription, source?: object): boolean { + // COMPAT(workspaceSetupObservation): added in v0.12.0, remove global setup delivery after 2027-04-19 once client floor >= v0.12.0. + if ( + event === "workspace_setup_progress" && + source && + this.supportsForSource(CLIENT_CAPS.workspaceSetupObservation, source) + ) + return false; for (const subscription of this.eventSubscriptions.values()) { - if ((!source || subscription.owner.source === source) && subscription.events.has(event)) + if ( + (!source || subscription.owner.source === source) && + subscription.events.has(event) && + !( + event === "workspace_setup_progress" && + this.supportsForSource(CLIENT_CAPS.workspaceSetupObservation, subscription.owner.source) + ) + ) return true; } if (!source && this.clientSources.size > 0) { @@ -8441,6 +8511,11 @@ export class Session { for (const subscription of this.eventSubscriptions.values()) { if ( !subscription.events.has(event) || + (event === "workspace_setup_progress" && + this.supportsForSource( + CLIENT_CAPS.workspaceSetupObservation, + subscription.owner.source, + )) || (onlySource && subscription.owner.source !== onlySource) ) continue; @@ -8464,6 +8539,11 @@ export class Session { private emit(msg: SessionOutboundMessage): void { if (!this.authorization.allowsOutbound(msg)) return; + if (msg.type === "workspace_setup_progress") { + const { workspaceId, subscriptionId: _subscriptionId, ...snapshot } = msg.payload; + this.workspaceSetupObservation.publish(workspaceId, snapshot); + return; + } if (this.delivery.reply(msg)) return; if (this.emitSubscribedEvent(msg)) return; // JSON.stringify(msg) is only computed when trace is enabled — it runs for @@ -8478,7 +8558,7 @@ export class Session { "agent.session.outbound", ); } - if (msg.type === "workspace_setup_progress" || msg.type === "workspace_setup_status_response") { + if (msg.type === "workspace_setup_status_response") { if (this.clientSources.size > 0 && this.onMessageToSource) { for (const [source] of this.clientSources) { this.onMessageToSource(source, this.workspaceSetupMessageForClient(msg, source)); @@ -8552,6 +8632,7 @@ export class Session { public async cleanup(): Promise { this.sessionLogger.trace({}, "agent.session.lifecycle.cleanup"); this.isCleanedUp = true; + this.unsubscribeSetupObservation(); await this.delivery.close(); if (this.unsubscribeAgentEvents) { diff --git a/packages/server/src/server/session.workspaces.test.ts b/packages/server/src/server/session.workspaces.test.ts index b9c04e8244..fafcbc182a 100644 --- a/packages/server/src/server/session.workspaces.test.ts +++ b/packages/server/src/server/session.workspaces.test.ts @@ -175,6 +175,7 @@ interface SessionTestAccess { emitWorkspaceUpdatesForWorkspaceIds(...args: unknown[]): Promise; emitWorkspaceUpdatesForExternalWorkspaceIds(workspaceIds: Iterable): Promise; updateClientCapabilities(capabilities: Record | null, source?: object): void; + publish: Session["publish"]; emit(message: unknown): void; onMessage(message: unknown): void; paseoHome: string; @@ -9602,3 +9603,82 @@ test("workspace.create.request reports an archived explicit project", async () = errorCode: "archived_project", }); }); + +test.each(["failed", "blocked"] as const)( + "workspace setup %s catches up from an existing directory cursor after releasing observation", + async (status) => { + const emitted: SessionOutboundMessage[] = []; + const session = createSessionForWorkspaceTests({ + onMessage: (message) => emitted.push(message), + }); + const source = {}; + const capabilities = { + [CLIENT_CAPS.ownedSubscriptions]: true, + [CLIENT_CAPS.workspaceSetupObservation]: true, + }; + session.updateClientCapabilities(capabilities, source); + await session.handleMessage( + { type: "fetch_workspaces_request", requestId: "before-setup", subscribe: {}, sync: {} }, + source, + ); + const initial = findByType(emitted, "fetch_workspaces_response")!.payload; + expect(initial.entries).toEqual([ + expect.objectContaining({ id: "ws-repo-running", setupStatus: null }), + ]); + expect(initial.sync?.mode).toBe("snapshot"); + await session.handleMessage( + { + type: "subscription.release.request", + requestId: "release-directory", + subscriptionId: initial.subscriptionId, + }, + source, + ); + emitted.length = 0; + session.publish({ + type: "workspace_setup_progress", + payload: { + workspaceId: "ws-repo-running", + status, + error: status === "failed" ? "setup failed" : null, + detail: { + type: "worktree_setup", + worktreePath: REPO_CWD, + branchName: "main", + log: "output never requested", + commands: [], + }, + }, + }); + await flushWorkspaceUpdateBackgroundWork(); + expect(emitted).toEqual([]); + const reconnectSource = {}; + session.updateClientCapabilities(capabilities, reconnectSource); + await session.handleMessage( + { + type: "fetch_workspaces_request", + requestId: "catch-up-setup", + subscribe: {}, + sync: { generation: initial.sync!.generation, afterSeq: initial.sync!.headSeq }, + }, + reconnectSource, + ); + const caughtUp = findByType(emitted, "fetch_workspaces_response")!.payload; + expect(caughtUp.sync?.mode).toBe("changes"); + expect(caughtUp.entries).toEqual([ + expect.objectContaining({ id: "ws-repo-running", setupStatus: status }), + ]); + expect(caughtUp.entries[0].syncSeq).toBeGreaterThan(initial.sync!.headSeq); + expect(filterByType(emitted, "workspace_setup_progress")).toEqual([]); + emitted.length = 0; + await session.handleMessage( + { + type: "fetch_workspaces_request", + requestId: "after-catch-up", + sync: { generation: caughtUp.sync!.generation, afterSeq: caughtUp.sync!.headSeq }, + }, + reconnectSource, + ); + expect(findByType(emitted, "fetch_workspaces_response")!.payload.entries).toEqual([]); + }, +); diff --git a/packages/server/src/server/test-utils/relay-latency-fixture.ts b/packages/server/src/server/test-utils/relay-latency-fixture.ts new file mode 100644 index 0000000000..5abcccf389 --- /dev/null +++ b/packages/server/src/server/test-utils/relay-latency-fixture.ts @@ -0,0 +1,75 @@ +import assert from "node:assert/strict"; +import dns from "node:dns"; +import { once } from "node:events"; +import net from "node:net"; +import { Writable } from "node:stream"; +import pino from "pino"; +import { WebSocketServer } from "ws"; +import { startRelayTransport } from "../relay-transport.js"; + +// Match the reported runtime even on Node versions with a newer default. +net.setDefaultAutoSelectFamilyAttemptTimeout(250); +const order = process.argv[2]; +assert.ok(order === "ipv4first" || order === "ipv6first"); +dns.setDefaultResultOrder(order); + +const logs: string[] = []; +const logger = pino( + { level: "debug" }, + new Writable({ + write(chunk, _encoding, callback) { + logs.push(chunk.toString()); + callback(); + }, + }), +); +const relay = new WebSocketServer({ host: "127.0.0.1", port: 0 }); +await once(relay, "listening"); +const address = relay.address(); +assert.ok(address && typeof address !== "string"); +relay.on("connection", (socket, request) => { + const url = new URL(request.url!, "http://relay-latency.test"); + if (url.searchParams.has("connectionId")) { + socket.on("message", (data) => socket.send(data)); + } else { + socket.send(JSON.stringify({ type: "sync", connectionIds: ["latency-client"] })); + } +}); + +let complete!: () => void; +let fail!: (error: Error) => void; +const delivered = new Promise((resolve, reject) => { + complete = resolve; + fail = reject; +}); +const deadline = setTimeout(() => fail(new Error(logs.join(""))), 8_000); +const transport = startRelayTransport({ + logger, + relayEndpoint: `relay-latency.test:${address.port}`, + relayUseTls: false, + serverId: "latency-server", + attachSocket: async (socket) => { + socket.on("message", (data) => { + try { + assert.equal(String(data), "latency round trip"); + complete(); + } catch (error) { + fail(error as Error); + } + }); + socket.send("latency round trip"); + }, +}); + +try { + await delivered; + assert.ok(logs.some((line) => JSON.parse(line).msg === "relay_control_connected")); + assert.ok(logs.some((line) => JSON.parse(line).msg === "relay_data_connected")); + assert.ok(!logs.some((line) => JSON.parse(line).msg === "relay_error")); + console.log("relay data round trip passed"); +} finally { + clearTimeout(deadline); + await transport.stop(); + for (const socket of relay.clients) socket.terminate(); + await new Promise((resolve) => relay.close(() => resolve())); +} diff --git a/packages/server/src/server/websocket-server.ts b/packages/server/src/server/websocket-server.ts index e833a07ce3..b95e7696e2 100644 --- a/packages/server/src/server/websocket-server.ts +++ b/packages/server/src/server/websocket-server.ts @@ -22,7 +22,6 @@ import { type ServerInfoStatusPayload, type ScriptStatusUpdateMessage, type SessionOutboundMessage, - type WorkspaceSetupSnapshot, type WSHelloMessage, type WSInboundMessage, WSInboundMessageSchema, @@ -43,6 +42,7 @@ import { type SessionRuntimeMetrics, } from "./session.js"; import type { HubRelationshipManagement } from "./hub/relationship-controller.js"; +import { WorkspaceSetupObservation } from "./workspace-setup-observation.js"; import { WorkspaceSetupRuntime } from "./workspace-setup-runtime.js"; import type { HubExecutionAgents } from "./hub/daemon-executions.js"; import type { AgentProvider } from "./agent/agent-sdk-types.js"; @@ -570,7 +570,7 @@ export class VoiceAssistantWebSocketServer { } | null; private readonly voiceSpeakHandlers = new Map(); private readonly voiceCallerContexts = new Map(); - private readonly workspaceSetupSnapshots = new Map(); + private readonly workspaceSetupObservation = new WorkspaceSetupObservation(); private readonly workspaceSetupRuntime: WorkspaceSetupRuntime; private readonly providerSnapshotManager: ProviderSnapshotManager; private onLifecycleIntent!: ((intent: SessionLifecycleIntent) => void) | null; @@ -955,6 +955,13 @@ export class VoiceAssistantWebSocketServer { } public broadcast(message: WSOutboundMessage): void { + // External setup producers (MCP and schedules) publish once, including when no + // clients are connected. Session-owned observers perform the source routing. + if (message.type === "session" && message.message.type === "workspace_setup_progress") { + const { workspaceId, subscriptionId: _subscriptionId, ...snapshot } = message.message.payload; + this.workspaceSetupObservation.publish(workspaceId, snapshot); + return; + } if (message.type === "session") { for (const connection of new Set(this.sessions.values())) { connection.session.publish(message.message); @@ -1506,7 +1513,7 @@ export class VoiceAssistantWebSocketServer { hubRelationships: options.hubRelationships, serviceProxy: this.serviceProxy ?? undefined, scriptRuntimeStore: this.scriptRuntimeStore ?? undefined, - workspaceSetupSnapshots: this.workspaceSetupSnapshots, + workspaceSetupObservation: this.workspaceSetupObservation, workspaceSetupRuntime: this.workspaceSetupRuntime, onBranchChanged: this.onBranchChanged ?? undefined, getDaemonTcpPort: this.getDaemonTcpPort ?? undefined, @@ -1803,6 +1810,7 @@ export class VoiceAssistantWebSocketServer { ...(this.workspaceLabelService ? { workspaceLabels: true } : {}), // COMPAT(workspaceSetupRun): added in v0.7.3, remove gate after 2027-09-02. workspaceSetupRun: true, + workspaceSetupObservation: true, // COMPAT(providersSnapshot): keep optional until all clients rely on snapshot flow. providersSnapshot: true, // COMPAT(providersSnapshotCwd): added in v0.3.2, remove gate after 2027-02-10. diff --git a/packages/server/src/server/wire-compat.test.ts b/packages/server/src/server/wire-compat.test.ts index 34abdebc3f..22c8661544 100644 --- a/packages/server/src/server/wire-compat.test.ts +++ b/packages/server/src/server/wire-compat.test.ts @@ -15,6 +15,7 @@ import { type SessionOutboundMessage, } from "@getpaseo/protocol/messages"; import { Session, type SessionOptions } from "./session.js"; +import { WorkspaceSetupObservation } from "./workspace-setup-observation.js"; import { OWNER_PERMISSIONS } from "./authorization/index.js"; import { DirectorySyncService } from "./directory-sync/index.js"; import { createProviderSnapshotManagerStub } from "./test-utils/session-stubs.js"; @@ -190,6 +191,7 @@ function createSessionForWireCompatTest(options?: { messages?: SessionOutboundMessage[]; onMessageToSource?: SessionOptions["onMessageToSource"]; rows?: AgentTimelineRow[]; + workspaceRegistry?: SessionOptions["workspaceRegistry"]; }): Session { const messages = options?.messages ?? []; const rows: AgentTimelineRow[] = [ @@ -228,7 +230,8 @@ function createSessionForWireCompatTest(options?: { agentStorage: new EmptyAgentStorage() as unknown as SessionOptions["agentStorage"], projectRegistry: new EmptyProjectRegistry() as unknown as SessionOptions["projectRegistry"], workspaceRegistry: - new EmptyWorkspaceRegistry() as unknown as SessionOptions["workspaceRegistry"], + options?.workspaceRegistry ?? + (new EmptyWorkspaceRegistry() as unknown as SessionOptions["workspaceRegistry"]), directorySync: options?.directorySync, scheduleService: {} as SessionOptions["scheduleService"], checkoutDiffManager: { @@ -641,3 +644,165 @@ test("setup progress is adapted per socket without changing the canonical snapsh expect(message.payload.status).toBe("blocked"); await session.cleanup(); }); + +test("scoped setup clients never receive session-wide setup output", async () => { + const messages: SessionOutboundMessage[] = []; + const session = createSessionForWireCompatTest({ + messages, + clientCapabilities: { owned_subscriptions: true, workspace_setup_observation: true }, + }); + const source = {}; + session.updateClientCapabilities( + { owned_subscriptions: true, workspace_setup_observation: true }, + source, + ); + await session.handleMessage( + { + type: "session.events.set_subscription.request", + requestId: "events", + events: ["workspace_setup_progress"], + }, + source, + ); + messages.length = 0; + for (const workspaceId of ["setup-a", "setup-b", "setup-c"]) { + for (let chunk = 0; chunk < 10; chunk++) { + session.publish({ + type: "workspace_setup_progress", + payload: { + workspaceId, + status: "running", + error: null, + detail: { + type: "worktree_setup", + worktreePath: "/workspace", + branchName: "setup", + log: "output".repeat(chunk * 1000), + commands: [], + }, + }, + }); + } + } + expect(messages).toEqual([]); + await session.cleanup(); +}); + +test("setup output invalidates directory metadata only when visible setup status changes", () => { + const setup = new WorkspaceSetupObservation(); + const earlier = { + status: "failed" as const, + error: "failed before any connection", + detail: { + type: "worktree_setup" as const, + worktreePath: "/workspace", + branchName: "test", + log: "earlier output", + commands: [], + }, + }; + setup.publish("earlier", earlier); + expect(setup.get("earlier")).toEqual(earlier); + expect(setup.status({ workspaceId: "earlier", untrustedSource: null })).toBe("failed"); + const changes: boolean[] = []; + setup.subscribe((_workspaceId, _snapshot, changed) => changes.push(changed)); + const detail = { + type: "worktree_setup" as const, + worktreePath: "/workspace", + branchName: "test", + log: "", + commands: [ + { + index: 0, + command: "setup", + cwd: "/workspace", + log: "", + status: "running" as const, + exitCode: null, + }, + ], + }; + for (const log of ["", "one", "one two", "one two three"]) + setup.publish("workspace", { status: "running", error: null, detail: { ...detail, log } }); + setup.publish("workspace", { status: "failed", error: "failed", detail }); + expect(changes).toEqual([true, false, false, false, true]); + expect(setup.status({ workspaceId: "workspace", untrustedSource: null })).toBe("failed"); + expect(setup.status({ workspaceId: "empty", untrustedSource: null })).toBeNull(); + setup.publish("empty", { status: "completed", error: null, detail: { ...detail, commands: [] } }); + expect(setup.status({ workspaceId: "empty", untrustedSource: null })).toBeNull(); +}); + +test("setup observation includes a transition that happens during its initial registry read", async () => { + let completeRead!: (value: null) => void; + let readStarted!: () => void; + const started = new Promise((resolve) => { + readStarted = resolve; + }); + const pendingRead = new Promise((resolve) => { + completeRead = resolve; + }); + const messages: SessionOutboundMessage[] = []; + const source = {}; + const session = createSessionForWireCompatTest({ + messages, + clientCapabilities: { owned_subscriptions: true, workspace_setup_observation: true }, + workspaceRegistry: { + get: () => { + readStarted(); + return pendingRead; + }, + list: () => [], + } as unknown as SessionOptions["workspaceRegistry"], + }); + session.updateClientCapabilities( + { owned_subscriptions: true, workspace_setup_observation: true }, + source, + ); + try { + const request = session.handleMessage( + { type: "workspace.setup.subscribe.request", workspaceId: "setup", requestId: "observe" }, + source, + ); + await started; + session.publish({ + type: "workspace_setup_progress", + payload: { + workspaceId: "setup", + status: "failed", + error: "bootstrap failure", + detail: { + type: "worktree_setup", + worktreePath: "/workspace", + branchName: "test", + log: "failure output", + commands: [], + }, + }, + }); + completeRead(null); + await request; + expect(messages).toEqual([ + { + type: "workspace.setup.subscribe.response", + payload: { + requestId: "observe", + workspaceId: "setup", + subscriptionId: expect.any(String), + snapshot: { + status: "failed", + error: "bootstrap failure", + detail: { + type: "worktree_setup", + worktreePath: "/workspace", + branchName: "test", + log: "failure output", + commands: [], + }, + }, + }, + }, + ]); + } finally { + await session.cleanup(); + } +}); diff --git a/packages/server/src/server/workspace-create-worktree-source.e2e.test.ts b/packages/server/src/server/workspace-create-worktree-source.e2e.test.ts index 69c1da2efc..6e757c3770 100644 --- a/packages/server/src/server/workspace-create-worktree-source.e2e.test.ts +++ b/packages/server/src/server/workspace-create-worktree-source.e2e.test.ts @@ -6,6 +6,13 @@ import path from "node:path"; import { expect, onTestFinished, test } from "vitest"; import { DaemonClient } from "./test-utils/index.js"; +import { WebSocket } from "ws"; +import { Client } from "@modelcontextprotocol/sdk/client/index.js"; +import { StreamableHTTPClientTransport } from "@modelcontextprotocol/sdk/client/streamableHttp.js"; +import { + DaemonClient as SocketDaemonClient, + type WebSocketLike, +} from "@getpaseo/client/internal/daemon-client"; import { createTestPaseoDaemon } from "./test-utils/paseo-daemon.js"; // The reshaped workspace.create.request forwards its worktree `source` @@ -596,3 +603,246 @@ async function expectMissingLocalMergeTarget({ client, cwd }: RestorableWorkspac ).error?.message, ).toContain("No local merge target is recorded"); } + +// Setup output is opt-in even for multiple sockets sharing one logical client. +test("setup details follow one workspace/source and restore after reconnect with minimal directory status", async () => { + const daemon = await createTestPaseoDaemon({ mcpEnabled: true }); + const { repoDir, tempRoot } = createGitRepoWithBranch(); + const clients: SocketDaemonClient[] = []; + const sockets = new Map(); + const observations: Array<{ release(): Promise }> = []; + const workspaces: Array<{ id: string; workspaceDirectory?: string }> = []; + const mcp = new Client({ name: "setup-test", version: "1.0.0" }); + try { + await mcp.connect( + new StreamableHTTPClientTransport(new URL(`http://127.0.0.1:${daemon.port}/mcp/agents`)), + ); + writeFileSync( + path.join(repoDir, "paseo.json"), + JSON.stringify({ worktree: { setup: "node setup.cjs" } }), + ); + writeFileSync( + path.join(repoDir, "setup.cjs"), + ` +const fs = require('node:fs'); +console.log('setup started'); +fs.writeFileSync('started.txt', 'ready'); +let wave = 0; +const timer = setInterval(() => { + if (fs.existsSync('wave-' + wave)) { + console.log('wave-' + wave + ':' + 'setup output '.repeat(1000)); + fs.writeFileSync('emitted-' + wave, 'ready'); + wave++; + } + if (fs.existsSync('finish.txt')) { clearInterval(timer); process.exit(1); } +}, 20); +`, + ); + writeFileSync(path.join(repoDir, ".gitignore"), "*.txt\nwave-*\nemitted-*\n"); + execFileSync("git", ["add", "paseo.json", "setup.cjs", ".gitignore"], { cwd: repoDir }); + execFileSync("git", ["-c", "commit.gpgsign=false", "commit", "-m", "setup fixture"], { + cwd: repoDir, + stdio: "pipe", + }); + const connect = async (clientId: string) => { + const client = new SocketDaemonClient({ + url: `ws://127.0.0.1:${daemon.port}/ws`, + clientId, + reconnect: { baseDelayMs: 10, maxDelayMs: 10 }, + webSocketFactory: (url) => { + const socket = new WebSocket(url); + sockets.set(clientId, [...(sockets.get(clientId) ?? []), socket]); + return socket as unknown as WebSocketLike; + }, + }); + clients.push(client); + await client.connect(); + return client; + }; + const creator = await connect("setup-creator"); + const viewer = await connect("setup-viewer"); + const sibling = await connect("setup-viewer"); + const quiet = await connect("setup-quiet"); + const viewerMessages: import("@getpaseo/protocol/messages").SessionOutboundMessage[] = []; + const quietMessages: import("@getpaseo/protocol/messages").SessionOutboundMessage[] = []; + const siblingMessages: import("@getpaseo/protocol/messages").SessionOutboundMessage[] = []; + viewer.subscribeRawMessages((message) => viewerMessages.push(message)); + quiet.subscribeRawMessages((message) => quietMessages.push(message)); + sibling.subscribeRawMessages((message) => siblingMessages.push(message)); + const directory = quiet.observeWorkspaces(); + observations.push(directory); + await directory.ready; + for (const worktreeSlug of ["noisy-a", "noisy-b", "noisy-c"]) { + const result = await creator.createWorkspace({ + source: { kind: "worktree", cwd: repoDir, worktreeSlug }, + }); + if (!result.workspace || result.error) throw new Error(result.error ?? "No workspace"); + workspaces.push(result.workspace); + await expect + .poll(() => existsSync(path.join(result.workspace!.workspaceDirectory!, "started.txt"))) + .toBe(true); + } + const external = await mcp.callTool({ + name: "create_workspace", + arguments: { isolation: "worktree", path: repoDir, worktreeSlug: "noisy-mcp" }, + }); + if (typeof external.structuredContent?.workspaceId !== "string") + throw new Error("Missing MCP workspace"); + const externalWorkspace = (await creator.fetchWorkspaces()).entries.find( + (entry) => entry.id === external.structuredContent!.workspaceId, + ); + if (!externalWorkspace) throw new Error("Missing MCP directory entry"); + workspaces.unshift(externalWorkspace); + await expect + .poll(() => existsSync(path.join(externalWorkspace.workspaceDirectory!, "started.txt"))) + .toBe(true); + const workspace = workspaces[0]!; + // The child writes its marker before the terminal's output is delivered. + // Wait for the daemon snapshot, rather than treating the file as an output barrier. + await expect + .poll(async () => (await viewer.fetchWorkspaceSetupStatus(workspace.id)).snapshot, { + timeout: 30000, + }) + .toMatchObject({ detail: { log: expect.stringContaining("setup started") } }); + const details = viewer.observeWorkspaceSetup(workspace.id); + observations.push(details); + const initial = await details.ready; + expect(initial.snapshot).toMatchObject({ + status: "running", + detail: { log: expect.stringContaining("setup started") }, + }); + await expect + .poll( + () => + new Set( + quietMessages + .filter( + (message) => + message.type === "workspace_update" && + message.payload.kind === "upsert" && + message.payload.workspace.setupStatus === "running", + ) + .map((message) => + message.type === "workspace_update" && message.payload.kind === "upsert" + ? message.payload.workspace.id + : "", + ), + ).size, + ) + .toBe(4); + for (const entry of workspaces) { + writeFileSync(path.join(entry.workspaceDirectory!, "wave-0"), "go"); + await expect + .poll(() => existsSync(path.join(entry.workspaceDirectory!, "emitted-0"))) + .toBe(true); + } + await expect + .poll( + () => + viewerMessages.filter( + (message) => + message.type === "workspace_setup_progress" && + message.payload.detail.log.includes("wave-0:"), + ).length, + ) + .toBeGreaterThan(0); + expect( + viewerMessages + .filter((message) => message.type === "workspace_setup_progress") + .map((message) => message.payload.workspaceId), + ).toEqual(expect.arrayContaining([workspace.id])); + expect( + new Set( + viewerMessages + .filter((message) => message.type === "workspace_setup_progress") + .map((message) => message.payload.workspaceId), + ), + ).toEqual(new Set([workspace.id])); + expect(quietMessages.filter((message) => message.type === "workspace_setup_progress")).toEqual( + [], + ); + expect( + siblingMessages.filter((message) => message.type === "workspace_setup_progress"), + ).toEqual([]); + for (const message of quietMessages) { + if (message.type !== "workspace_update" || message.payload.kind !== "upsert") continue; + expect(message.payload.workspace).not.toHaveProperty("detail"); + expect(message.payload.workspace).not.toHaveProperty("error"); + } + const waveLogs = viewerMessages + .filter( + (message) => + message.type === "workspace_setup_progress" && + message.payload.detail.log.includes("wave-0:"), + ) + .map((message) => + message.type === "workspace_setup_progress" ? message.payload.detail.log : "", + ); + expect(waveLogs.length).toBe(new Set(waveLogs).size); + const restoredSnapshots: unknown[] = []; + details.subscribe({ + snapshot: (snapshot) => restoredSnapshots.push(snapshot), + update: () => {}, + }); + const beforeReconnect = details.subscriptionId; + sockets.get("setup-viewer")![0]!.terminate(); + await expect.poll(() => restoredSnapshots.length, { timeout: 10000 }).toBe(2); + expect(details.subscriptionId).not.toBe(beforeReconnect); + expect(restoredSnapshots[1]).toMatchObject({ + snapshot: { detail: { log: expect.stringContaining("wave-0:") } }, + }); + const subscriptionId = details.subscriptionId; + await details.release(); + viewerMessages.length = 0; + writeFileSync(path.join(workspace.workspaceDirectory!, "wave-1"), "go"); + await expect + .poll(() => existsSync(path.join(workspace.workspaceDirectory!, "emitted-1"))) + .toBe(true); + // Wait until the daemon has consumed the output before checking wire silence. + await expect + .poll( + async () => (await viewer.fetchWorkspaceSetupStatus(workspace.id)).snapshot?.detail.log, + { + timeout: 30000, + }, + ) + .toContain("wave-1:"); + expect(viewerMessages.filter((message) => message.type === "workspace_setup_progress")).toEqual( + [], + ); + const resumed = viewer.observeWorkspaceSetup(workspace.id); + observations.push(resumed); + expect((await resumed.ready).snapshot?.detail.log).toContain("wave-1:"); + expect(resumed.subscriptionId).not.toBe(subscriptionId); + writeFileSync(path.join(workspaces[1]!.workspaceDirectory!, "finish.txt"), "fail"); + await expect + .poll( + () => + quietMessages.filter( + (message) => + message.type === "workspace_update" && + message.payload.kind === "upsert" && + message.payload.workspace.id === workspaces[1]!.id && + message.payload.workspace.setupStatus === "failed", + ).length, + { timeout: 30000 }, + ) + .toBe(1); + expect(quietMessages.filter((message) => message.type === "workspace_setup_progress")).toEqual( + [], + ); + await resumed.release(); + await directory.release(); + } finally { + // End every fixture command and release observations while transports are live, + // including when an assertion fails before the normal release path. + for (const workspace of workspaces) { + writeFileSync(path.join(workspace.workspaceDirectory!, "finish.txt"), "stop"); + } + for (const observation of observations) await observation.release(); + await mcp.close(); + for (const client of clients) await client.close(); + await daemon.close(); + await rm(tempRoot, { recursive: true, force: true, maxRetries: 10, retryDelay: 100 }); + } +}, 180000); diff --git a/packages/server/src/server/workspace-setup-observation.ts b/packages/server/src/server/workspace-setup-observation.ts new file mode 100644 index 0000000000..69ad434f57 --- /dev/null +++ b/packages/server/src/server/workspace-setup-observation.ts @@ -0,0 +1,56 @@ +import type { PersistedWorkspaceRecord } from "./workspace-registry.js"; +import type { WorkspaceSetupSnapshot } from "@getpaseo/protocol/messages"; + +type Listener = ( + workspaceId: string, + snapshot: WorkspaceSetupSnapshot, + statusChanged: boolean, +) => void; + +/** Daemon-owned setup snapshots, shared by sessions; output never invalidates the directory. */ +export class WorkspaceSetupObservation { + private readonly listeners = new Set(); + private readonly statuses = new Map(); + + private readonly snapshots = new Map(); + + get(workspaceId: string): WorkspaceSetupSnapshot | undefined { + return this.snapshots.get(workspaceId); + } + + cache(workspaceId: string, snapshot: WorkspaceSetupSnapshot): void { + this.snapshots.set(workspaceId, snapshot); + } + + publish(workspaceId: string, snapshot: WorkspaceSetupSnapshot): void { + const status = this.summary(snapshot); + const statusChanged = (this.statuses.get(workspaceId) ?? null) !== status; + this.statuses.set(workspaceId, status); + this.snapshots.set(workspaceId, snapshot); + for (const listener of this.listeners) listener(workspaceId, snapshot, statusChanged); + } + + status( + workspace: Pick, + ): WorkspaceSetupSnapshot["status"] | null { + const snapshot = this.snapshots.get(workspace.workspaceId); + if (snapshot) return this.summary(snapshot); + return workspace.untrustedSource ? "blocked" : null; + } + + private summary(snapshot: WorkspaceSetupSnapshot): WorkspaceSetupSnapshot["status"] | null { + if ( + snapshot.status === "failed" || + snapshot.status === "blocked" || + snapshot.error !== null || + snapshot.detail.commands.length > 0 + ) + return snapshot.status; + return null; + } + + subscribe(listener: Listener): () => void { + this.listeners.add(listener); + return () => this.listeners.delete(listener); + } +} diff --git a/packages/server/src/server/worktree-session.ts b/packages/server/src/server/worktree-session.ts index 82f0113bd5..02b1625228 100644 --- a/packages/server/src/server/worktree-session.ts +++ b/packages/server/src/server/worktree-session.ts @@ -164,7 +164,7 @@ export type CreatePaseoWorktreeWorkflowFn = ( interface HandleWorkspaceSetupStatusRequestDependencies { emit: EmitSessionMessage; - workspaceSetupSnapshots: ReadonlyMap; + workspaceSetupSnapshots: Pick, "get">; getWorkspace: (workspaceId: string) => Promise; } diff --git a/packages/server/src/terminal/terminal-worker-process.ts b/packages/server/src/terminal/terminal-worker-process.ts index 4e16f8de04..a70d37c5b9 100644 --- a/packages/server/src/terminal/terminal-worker-process.ts +++ b/packages/server/src/terminal/terminal-worker-process.ts @@ -125,6 +125,7 @@ function watchTerminal(session: TerminalSession): void { type: "terminalMessage", terminalId: session.id, message: { type: "output", data: payload.toString("utf8"), revision }, + replayPreamble: session.getReplayPreamble(), }); }, }); @@ -144,6 +145,7 @@ function watchTerminal(session: TerminalSession): void { type: "terminalMessage", terminalId: session.id, message, + replayPreamble: session.getReplayPreamble(), }); }, // Creation already sends an authoritative state in terminalCreated. A second diff --git a/packages/server/src/terminal/terminal-worker-protocol.ts b/packages/server/src/terminal/terminal-worker-protocol.ts index 6b722c978a..5e7d1a30c0 100644 --- a/packages/server/src/terminal/terminal-worker-protocol.ts +++ b/packages/server/src/terminal/terminal-worker-protocol.ts @@ -121,6 +121,7 @@ export type TerminalWorkerEvent = type: "terminalMessage"; terminalId: string; message: ServerMessage; + replayPreamble: string; } | { type: "terminalExit"; diff --git a/packages/server/src/terminal/worker-terminal-manager.ts b/packages/server/src/terminal/worker-terminal-manager.ts index ca84cfe622..0a1adb2c44 100644 --- a/packages/server/src/terminal/worker-terminal-manager.ts +++ b/packages/server/src/terminal/worker-terminal-manager.ts @@ -67,8 +67,7 @@ interface WorkerTerminalRecord { state: TerminalState; activity: TerminalActivity | null; // Cached input-mode preamble from the worker (the authoritative tracker lives - // in the worker process). Refreshed on every getTerminalState response and on - // the snapshotReady event that precedes a live-restore replay. + // in the worker process). Updated with streamed output and snapshot responses. replayPreamble: string; exitInfo: TerminalExitInfo | null; messageListeners: Set<(msg: ServerMessage) => void>; @@ -356,11 +355,6 @@ export function createWorkerTerminalManager( }; }, getReplayPreamble(): string { - // Refreshed from every getTerminalState response, which the controller fetches - // before every snapshot replay (legacy + visible-snapshot restore). The one - // gap is restore.mode === "live", which replays without fetching state — there - // this can be stale/empty. No client sends "live" today; revisit (ship the - // preamble on the worker's snapshotReady) if one ever does. return record.replayPreamble; }, getTitle(): string | undefined { @@ -429,9 +423,7 @@ export function createWorkerTerminalManager( if (message.message.type === "snapshot") { record.state = message.message.state; } - if (message.message.type === "snapshotReady" && message.message.replayPreamble !== undefined) { - record.replayPreamble = message.message.replayPreamble; - } + record.replayPreamble = message.replayPreamble; for (const listener of Array.from(record.messageListeners)) { listener(message.message); } diff --git a/packages/server/src/utils/directory-suggestions.test.ts b/packages/server/src/utils/directory-suggestions.test.ts index 711a721e48..72c77a4ce2 100644 --- a/packages/server/src/utils/directory-suggestions.test.ts +++ b/packages/server/src/utils/directory-suggestions.test.ts @@ -1,5 +1,5 @@ import { createHook } from "node:async_hooks"; -import { execFileSync } from "node:child_process"; +import { execFileSync, spawn, type ChildProcess } from "node:child_process"; import { mkdtempSync, mkdirSync, @@ -1066,6 +1066,16 @@ describe("relative typed-entry configuration", () => { }); }); +interface SearchProcessExit { + code: number | null; + signal: string | null; +} + +interface SearchProcess { + child: ChildProcess; + exited: Promise; +} + // Reading a tree is cheap; re-deriving each entry's path state is not. A scan that asks whether // every ancestor of every entry is inside the root, or is Git-ignored, costs multiples of the // read and is what made large home directories exceed the client request timeout. @@ -1073,6 +1083,7 @@ describe("home-tree scan cost", () => { const DEPTH = 8; const CHAINS = 40; let scanRoot: string; + let searchProcess: SearchProcess | null = null; beforeEach(() => { scanRoot = realpathSync.native(mkdtempSync(path.join(tmpdir(), "directory-scan-cost-"))); @@ -1083,8 +1094,16 @@ describe("home-tree scan cost", () => { } }); - afterEach(() => { - rmSync(scanRoot, { recursive: true, force: true }); + afterEach(async () => { + try { + if (searchProcess) { + searchProcess.child.kill(); + await searchProcess.exited; + } + } finally { + searchProcess = null; + rmSync(scanRoot, { recursive: true, force: true }); + } }); // Nothing matches, so the scan walks the whole tree instead of stopping at a confident result. @@ -1102,6 +1121,82 @@ describe("home-tree scan cost", () => { return stopPathContainmentMetrics(); } + // Creating the 27,000-directory fixture alone takes about 20 s on Windows + // runners under parallel load, and it has crossed the default 30 s deadline. + // The heap bound is enforced by the child's --max-old-space-size and its own + // 20 s timeout, so the test deadline only has to cover fixture setup. + it("finishes overlapping broad-tree searches within a bounded heap", async () => { + const broadRoot = path.join(scanRoot, "broad"); + mkdirSync(broadRoot); + for (let branch = 0; branch < 30; branch += 1) { + const branchRoot = path.join(broadRoot, `branch-${branch}`); + mkdirSync(branchRoot); + for (let group = 0; group < 30; group += 1) { + const groupRoot = path.join(branchRoot, `group-${group}`); + mkdirSync(groupRoot); + for (let leaf = 0; leaf < 30; leaf += 1) { + mkdirSync(path.join(groupRoot, `leaf-${leaf}`)); + } + } + } + // A smaller real tree and explicit heap budget keep the million-directory repro cheap in CI. + const moduleUrl = new URL("./directory-suggestions.ts", import.meta.url).href; + const source = ` + const { searchDirectoryEntries } = await import(${JSON.stringify(moduleUrl)}); + const results = await Promise.all(Array.from({ length: 14 }, (_, index) => + searchDirectoryEntries({ + root: ${JSON.stringify(broadRoot)}, + query: "z".repeat(index + 1), + pathFormat: "absolute", + includeFiles: false, + includeDirectories: true, + pathQueryPolicy: "rooted", + rootAliases: ["~"], + blankQueryBehavior: "none", + confidentResultScanThreshold: 5000, + maxEntriesScanned: 2000, + limit: 30, + }) + )); + process.stdout.write(JSON.stringify(results)); + `; + const child = spawn( + process.execPath, + [ + "--max-old-space-size=128", + "--conditions=source", + "--import", + "tsx", + "--input-type=module", + "--eval", + source, + ], + { stdio: ["ignore", "pipe", "pipe"], timeout: 20_000 }, + ); + let stdout = ""; + let stderr = ""; + child.stdout.setEncoding("utf8"); + child.stderr.setEncoding("utf8"); + child.stdout.on("data", (chunk: string) => { + stdout += chunk; + }); + child.stderr.on("data", (chunk: string) => { + stderr += chunk; + }); + const exited = new Promise((resolve, reject) => { + child.on("error", reject); + child.on("close", (code, signal) => resolve({ code, signal })); + }); + searchProcess = { child, exited }; + const exit = await exited; + expect({ ...exit, outOfMemory: stderr.includes("heap out of memory") }).toEqual({ + code: 0, + signal: null, + outOfMemory: false, + }); + expect(JSON.parse(stdout)).toEqual(Array.from({ length: 14 }, () => [])); + }, 120_000); + it("derives no containment for a tree that cannot leave the root", async () => { const checks = await countContainmentChecks(scanWholeTree); diff --git a/packages/server/src/utils/directory-suggestions.ts b/packages/server/src/utils/directory-suggestions.ts index e0443475bc..e731ccef0f 100644 --- a/packages/server/src/utils/directory-suggestions.ts +++ b/packages/server/src/utils/directory-suggestions.ts @@ -63,6 +63,13 @@ interface WalkStart { resolvedPath: string; } +interface WalkChildrenOptions { + parent: WalkStart; + depth: number; + input: SearchInput; + visited: Set; +} + interface TraversedEntry extends ChildEntry { visiblePath: string; depth: number; @@ -318,17 +325,18 @@ async function searchChildren(input: SearchInput): Promise { const discoveryInput = isInsideExcludedPath(parent, input) ? { ...input, excludedDiscoveryPaths: new Set() } : input; - const entries = await readChildren(parent); - return entries.flatMap((entry) => { + const ranked: RankedEntry[] = []; + for await (const entry of readChildren(parent)) { if (!isPathInsideRoot(input.root, entry.resolvedPath) || !shouldDiscover(entry, discoveryInput)) - return []; + continue; const candidate: TraversedEntry = { ...entry, visiblePath: path.join(visibleParent, entry.name), depth: 1, }; - return shouldSuggest(candidate, input) ? [rank(candidate, input)] : []; - }); + if (shouldSuggest(candidate, input)) ranked.push(rank(candidate, input)); + } + return ranked; } async function searchTree( @@ -336,21 +344,8 @@ async function searchTree( start: WalkStart = { visiblePath: input.root, resolvedPath: input.root }, ): Promise { if (!(input.maxEntriesScanned > 0)) return []; - const roots = (await readChildren(start.resolvedPath)).filter((entry) => - staysInsideRoot(entry, input.root), - ); const visited = new Set([start.resolvedPath]); - const branches = roots.flatMap((entry) => - shouldDiscover(entry, input) - ? [ - walkBranch( - { ...entry, visiblePath: path.join(start.visiblePath, entry.name), depth: 1 }, - input, - visited, - ), - ] - : [], - ); + const branches = walkChildren({ parent: start, depth: 1, input, visited }); const ranked: RankedEntry[] = []; let scanned = 0; const threshold = input.confidentResultScanThreshold; @@ -381,38 +376,39 @@ async function* walkBranch( ) return; visited.add(entry.resolvedPath); - const children = (await readChildren(entry.resolvedPath)).filter((child) => - staysInsideRoot(child, input.root), - ); - const branches = children.flatMap((child) => - shouldDiscover(child, input) - ? [ - walkBranch( - { - ...child, - visiblePath: path.join(entry.visiblePath, child.name), - depth: entry.depth + 1, - }, - input, - visited, - ), - ] - : [], - ); - yield* roundRobin(branches); + yield* roundRobin(walkChildren({ parent: entry, depth: entry.depth + 1, input, visited })); } -async function* roundRobin(branches: Array>): AsyncGenerator { - let active = branches; - while (active.length) { +// Create a child's path and iterator only when its branch gets a turn. Eagerly constructing every +// sibling's subtree retained hundreds of thousands of unvisited children beyond the scan budget. +async function* walkChildren({ + parent, + depth, + input, + visited, +}: WalkChildrenOptions): AsyncGenerator> { + for await (const child of readChildren(parent.resolvedPath)) { + if (!staysInsideRoot(child, input.root) || !shouldDiscover(child, input)) continue; + yield walkBranch( + { ...child, visiblePath: path.join(parent.visiblePath, child.name), depth }, + input, + visited, + ); + } +} + +async function* roundRobin(branches: AsyncIterable>): AsyncGenerator { + let active: AsyncIterable> | Array> = branches; + while (true) { const nextRound: Array> = []; - for (const branch of active) { + for await (const branch of active) { const next = await branch.next(); if (!next.done) { nextRound.push(branch); yield next.value; } } + if (!nextRound.length) return; active = nextRound; } } @@ -742,9 +738,9 @@ async function resolveDirectory(inputPath: string): Promise { return info?.isDirectory() ? resolved : null; } -async function readChildren(directory: string): Promise { +async function* readChildren(directory: string): AsyncGenerator { const directoryInfo = await stat(directory).catch(() => null); - if (!directoryInfo?.isDirectory()) return []; + if (!directoryInfo?.isDirectory()) return; const cached = CAN_VALIDATE_DIRECTORY_CACHE_FROM_METADATA ? directoryListCache.get(directory) @@ -774,9 +770,10 @@ async function readChildren(directory: string): Promise { } } - return (await Promise.all(rawEntries.map((entry) => resolveChild(directory, entry)))) - .filter((entry): entry is ChildEntry => entry !== null) - .sort((left, right) => left.name.localeCompare(right.name)); + for (const rawEntry of rawEntries) { + const entry = await resolveChild(directory, rawEntry); + if (entry) yield entry; + } } async function loadGitIgnoredPaths(root: string): Promise> { diff --git a/packages/server/vitest.config.ts b/packages/server/vitest.config.ts index c80345c79e..9f3717a9bc 100644 --- a/packages/server/vitest.config.ts +++ b/packages/server/vitest.config.ts @@ -19,9 +19,6 @@ export default defineConfig({ setupFiles: [path.resolve(__dirname, "./src/test-utils/vitest-setup.ts")], pool: "forks", fileParallelism: false, - // Even two concurrent Git-heavy suites can exhaust Windows test deadlines. - // Run files serially so their subprocesses do not compete across suites. - maxWorkers: process.platform === "win32" ? 1 : undefined, exclude: ["**/node_modules/**", "**/dist/**", "**/.claude/**", "**/.dev/**"], }, }); diff --git a/packages/website/e2e/agent-icons.spec.ts b/packages/website/e2e/agent-icons.spec.ts new file mode 100644 index 0000000000..4bc828475e --- /dev/null +++ b/packages/website/e2e/agent-icons.spec.ts @@ -0,0 +1,26 @@ +import { expect, test, type Page } from "playwright/test"; + +test("keeps unrelated agent artwork unchanged while adding the Hermes mark", async ({ page }) => { + await openSupportedAgents(page); + await expectGenericAgentMark(page, "CodeWhale"); + await expectVendoredAgentMark(page, "Hermes Agent"); +}); + +async function openSupportedAgents(page: Page) { + await page.goto("/agents"); + await expect(page.getByRole("heading", { level: 1, name: "Supported agents" })).toBeVisible(); +} + +async function expectGenericAgentMark(page: Page, name: string) { + const card = page.getByRole("link", { name, exact: true }); + await expect(card).toBeVisible(); + // Decorative SVGs have no accessible role; the fallback is Lucide's bot mark. + await expect(card.locator("svg.lucide-bot")).toBeVisible(); +} + +async function expectVendoredAgentMark(page: Page, name: string) { + const card = page.getByRole("link", { name, exact: true }); + await expect(card).toBeVisible(); + await expect(card.locator("svg")).toBeVisible(); + await expect(card.locator("svg.lucide-bot")).toHaveCount(0); +} diff --git a/packages/website/package.json b/packages/website/package.json index 3646d4da47..7700ad2052 100644 --- a/packages/website/package.json +++ b/packages/website/package.json @@ -1,6 +1,6 @@ { "name": "@getpaseo/website", - "version": "0.12.0-beta.1", + "version": "0.12.0", "private": true, "type": "module", "scripts": { diff --git a/packages/website/src/assets/agent-icons/hermes.svg b/packages/website/src/assets/agent-icons/hermes.svg new file mode 100644 index 0000000000..c6fdd22500 --- /dev/null +++ b/packages/website/src/assets/agent-icons/hermes.svg @@ -0,0 +1,3 @@ + + + diff --git a/patches/react-native-enriched-markdown+1.2.0-nightly-20261014-766fc0e67.patch b/patches/react-native-enriched-markdown+1.2.0-nightly-20261014-766fc0e67.patch index b41700d65b..d7e224d04d 100644 --- a/patches/react-native-enriched-markdown+1.2.0-nightly-20261014-766fc0e67.patch +++ b/patches/react-native-enriched-markdown+1.2.0-nightly-20261014-766fc0e67.patch @@ -652,6 +652,37 @@ index fde4b04..b524ea7 100644 } fun View.emitImagePressEvent( +diff --git a/node_modules/react-native-enriched-markdown/cpp/md4c/md4c.c b/node_modules/react-native-enriched-markdown/cpp/md4c/md4c.c +index 44d5134a4..feef5eec8 100644 +--- a/node_modules/react-native-enriched-markdown/cpp/md4c/md4c.c ++++ b/node_modules/react-native-enriched-markdown/cpp/md4c/md4c.c +@@ -4551,7 +4551,7 @@ md_analyze_permissive_autolink(MD_CTX* ctx, int mark_index) + /* Scan for path segment. */ + if(end < line_end && CH(end) == _T('/')) { + if(md_analyze_permissive_autolink_segment(ctx, end+1, line_end, &end, false, +- _T('/'), _T(".+-_~%"), NULL, &right_cursor) < 0) ++ _T('/'), _T(".+-_~%()"), NULL, &right_cursor) < 0) + return; + + /* Path can also end with additional '/' if its a directory. */ +@@ -4574,9 +4574,16 @@ md_analyze_permissive_autolink(MD_CTX* ctx, int mark_index) + } + } + ++ /* Sentence punctuation is not part of a permissive autolink. Trim only ++ * the final suffix, so dots inside paths and queries remain intact. ++ * Explicit Markdown destinations and angle-bracket autolinks do not use ++ * this analyzer and retain their authored punctuation. */ ++ while(end > beg && ISANYOF(end-1, _T(".,;:!?"))) ++ end--; ++ + /* Verify there's line boundary, whitespace, allowed punctuation or + * resolved closer mark just after the suspected autolink. */ +- if(end < line_end && !ISUNICODEWHITESPACE(end) && !ISANYOF(end, _T(")}].!?,;"))) { ++ if(end < line_end && !ISUNICODEWHITESPACE(end) && !ISANYOF(end, _T(")}].!?,;:"))) { + MD_MARK* mark; + + mark = md_scan_right_for_resolved_mark(ctx, right_cursor, end, &right_cursor); diff --git a/node_modules/react-native-enriched-markdown/cpp/parser/MD4CParser.cpp b/node_modules/react-native-enriched-markdown/cpp/parser/MD4CParser.cpp index c99a52d..c93aaf7 100644 --- a/node_modules/react-native-enriched-markdown/cpp/parser/MD4CParser.cpp @@ -1304,7 +1335,7 @@ diff --git a/node_modules/react-native-enriched-markdown/lib/module/web/renderer index dd70713..ca0385a 100644 --- a/node_modules/react-native-enriched-markdown/lib/module/web/renderers/BlockRenderers.js +++ b/node_modules/react-native-enriched-markdown/lib/module/web/renderers/BlockRenderers.js -@@ -101,12 +101,20 @@ function AdmonitionRenderer({ +@@ -101,12 +101,28 @@ function AdmonitionRenderer({ }); } function CodeBlockRenderer({ @@ -1317,14 +1348,34 @@ index dd70713..ca0385a 100644 const language = node.attributes?.language; + const CustomCodeBlock = capabilities.renderers?.codeBlock; + if (CustomCodeBlock) { -+ return /*#__PURE__*/_jsx(CustomCodeBlock, { -+ code: extractNodeText(node), -+ language: language ?? '' ++ // The custom renderer owns the block's look; the library keeps its spacing, ++ // including the zeroed trailing margin of the last block. ++ return /*#__PURE__*/_jsx("div", { ++ style: { ++ marginTop: styles.codeBlock.marginTop, ++ marginBottom: styles.codeBlock.marginBottom ++ }, ++ children: /*#__PURE__*/_jsx(CustomCodeBlock, { ++ code: extractNodeText(node), ++ language: language ?? '' ++ }) + }); + } const label = language ? `Code block: ${language}` : 'Code block'; if (callbacks.onCodeBlockPress == null) { return /*#__PURE__*/_jsx("pre", { +@@ -214,7 +230,10 @@ function ImageRenderer({ + src: url, + alt: alt, + title: title, +- style: imgStyle, ++ style: { ++ ...imgStyle, ++ cursor: 'zoom-in' ++ }, + role: "button", + tabIndex: 0, + "aria-label": alt, diff --git a/node_modules/react-native-enriched-markdown/lib/module/web/renderers/BlockRenderers.js.map b/node_modules/react-native-enriched-markdown/lib/module/web/renderers/BlockRenderers.js.map index dc917c4..cf59150 100644 --- a/node_modules/react-native-enriched-markdown/lib/module/web/renderers/BlockRenderers.js.map @@ -1359,12 +1410,15 @@ index 049421a..c05b993 100644 -{"version":3,"names":["useState","useEffect","extractNodeText","listItemStyle","checkedTaskTextStyle","jsx","_jsx","jsxs","_jsxs","NESTED_LIST_TYPES","Set","ListRenderer","node","styles","parentType","renderChildren","listTag","ListTag","isNested","hasTaskChild","children","some","child","attributes","isTask","resolvedStyle","listNested","listTask","list","style","UnorderedListRenderer","props","OrderedListRenderer","isNestedList","has","type","ListItemRenderer","index","callbacks","capabilities","initialChecked","taskChecked","taskText","isChecked","setIsChecked","handleChange","enableTaskListItemToggle","taskIndex","undefined","newChecked","onTaskListItemPress","checked","text","hasNestedList","checkedStyle","inlineNode","filter","nestedNode","onChange","readOnly","taskCheckbox","taskCheckboxDisabled","listRenderers","UnorderedList","OrderedList","ListItem"],"sourceRoot":"../../../../src","sources":["web/renderers/ListRenderers.tsx"],"mappings":"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","ignoreList":[]} +{"version":3,"names":["useState","useEffect","extractNodeText","listItemStyle","checkedTaskTextStyle","jsx","_jsx","jsxs","_jsxs","NESTED_LIST_TYPES","Set","ListRenderer","node","styles","parentType","renderChildren","listTag","ListTag","isNested","hasTaskChild","children","some","child","attributes","isTask","resolvedStyle","listNested","listTask","list","start","Number","undefined","style","UnorderedListRenderer","props","OrderedListRenderer","isNestedList","has","type","ListItemRenderer","index","callbacks","capabilities","initialChecked","taskChecked","taskText","isChecked","setIsChecked","handleChange","enableTaskListItemToggle","taskIndex","newChecked","onTaskListItemPress","checked","text","hasNestedList","checkedStyle","inlineNode","filter","nestedNode","onChange","readOnly","taskCheckbox","taskCheckboxDisabled","listRenderers","UnorderedList","OrderedList","ListItem"],"sourceRoot":"../../../../src","sources":["web/renderers/ListRenderers.tsx"],"mappings":"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","ignoreList":[]} diff --git a/node_modules/react-native-enriched-markdown/lib/module/web/wasm/md4c.js b/node_modules/react-native-enriched-markdown/lib/module/web/wasm/md4c.js -index 978a8c7..950cccd 100644 +index 978a8c761..25e525d91 100644 --- a/node_modules/react-native-enriched-markdown/lib/module/web/wasm/md4c.js +++ b/node_modules/react-native-enriched-markdown/lib/module/web/wasm/md4c.js -@@ -3,10 +3,11 @@ +@@ -1,15 +1,16 @@ + "use strict"; + var createMd4cModule = (() => { - var _scriptName = globalThis.document?.currentScript?.src; +- var _scriptName = globalThis.document?.currentScript?.src; ++ var _scriptName = typeof document != 'undefined' ? document.currentScript?.src : undefined; return async function (moduleArg = {}) { + var moduleRtn; var Module = moduleArg; @@ -1374,21 +1428,26 @@ index 978a8c7..950cccd 100644 + var arguments_ = []; var thisProgram = "./this.program"; var scriptDirectory = ""; - var readAsync; -@@ -30,8 +31,6 @@ var createMd4cModule = (() => { +- var readAsync; ++ var readAsync, readBinary; + if (ENVIRONMENT_IS_WEB || ENVIRONMENT_IS_WORKER) { + try { + scriptDirectory = new URL(".", _scriptName).href; +@@ -30,22 +31,13 @@ var createMd4cModule = (() => { var err = console.error.bind(console); var wasmBinary; var ABORT = false; - class EmscriptenEH {} - class EmscriptenSjLj extends EmscriptenEH {} - function binaryDecode(bin) { - for (var i = 0, l = bin.length, o = new Uint8Array(l), c; i < l; ++i) { - c = bin.charCodeAt(i); -@@ -39,13 +38,12 @@ var createMd4cModule = (() => { - } - return o; - } +- function binaryDecode(bin) { +- for (var i = 0, l = bin.length, o = new Uint8Array(l), c; i < l; ++i) { +- c = bin.charCodeAt(i); +- o[i] = ~c >> 8 & c; +- } +- return o; +- } + var readyPromiseResolve, readyPromiseReject; ++ var wasmMemory; + var HEAP8, HEAPU8, HEAP16, HEAPU16, HEAP32, HEAPU32, HEAPF32, HEAPF64; + var HEAP64, HEAPU64; var runtimeInitialized = false; @@ -1402,7 +1461,7 @@ index 978a8c7..950cccd 100644 HEAP8 = new Int8Array(b); HEAP16 = new Int16Array(b); HEAPU8 = new Uint8Array(b); -@@ -58,10 +56,11 @@ var createMd4cModule = (() => { +@@ -58,10 +50,11 @@ var createMd4cModule = (() => { HEAPU64 = new BigUint64Array(b); } function preRun() { @@ -1418,7 +1477,7 @@ index 978a8c7..950cccd 100644 } callRuntimeCallbacks(onPreRuns); } -@@ -70,25 +69,27 @@ var createMd4cModule = (() => { +@@ -70,28 +63,56 @@ var createMd4cModule = (() => { wasmExports["__wasm_call_ctors"](); } function postRun() { @@ -1434,6 +1493,23 @@ index 978a8c7..950cccd 100644 } callRuntimeCallbacks(onPostRuns); } ++ var runDependencies = 0; ++ var dependenciesFulfilled = null; ++ function addRunDependency(id) { ++ runDependencies++; ++ Module["monitorRunDependencies"]?.(runDependencies); ++ } ++ function removeRunDependency(id) { ++ runDependencies--; ++ Module["monitorRunDependencies"]?.(runDependencies); ++ if (runDependencies == 0) { ++ if (dependenciesFulfilled) { ++ var callback = dependenciesFulfilled; ++ dependenciesFulfilled = null; ++ callback(); ++ } ++ } ++ } function abort(what) { Module["onAbort"]?.(what); - what = `Aborted(${what})`; @@ -1448,20 +1524,47 @@ index 978a8c7..950cccd 100644 var wasmBinaryFile; function findWasmBinary() { - return binaryDecode('asm¬`````````````` ````||`~`|``Tenv __cxa_throwenv\r__assert_failenv _abort_js\nenvemscripten_resize_heap˜–\n\r\n\n\n   \r     \r \n  \n  p44€€@ A à€ ¢memory__wasm_call_ctors\rparseMarkdown__indirect_function_table_emscripten_stack_restore—_emscripten_stack_alloc˜emscripten_stack_get_current™ JA 3” \rq !"#$%&\'()s*B=DZfghq*‚‚„’†*‘އ*‹‰*“•–• (\nªº–æAàÚB7AèÚA6A÷ÚA:AìÚAØ\r(6AðÚAÜ\r-:AñÚA:AƒÛA:AøÚA±\r/;AúÚA³\r-:AûÚA:AÛA:A„ÛAŠ(6AˆÛAŽ-:A‰ÛA:A›ÛA :AÛA™ )7A˜ÛA¡ -:A™ÛA:A ÛB칻֮سå7A«ÛA:A¨ÛA:A·ÛA:A¬ÛAá\r(6A°ÛAå\r/;A²ÛA:A¸ÛAt"6A¼ÛB‹€€€€‚€€€7 AÆ(6 A¿)7 A: AÏÛA:AÄÛA¦ (6AÈÛAª -:AÉÛA:AÛÛA:AÐÛAÈ (6AÔÛAÌ -:AÕÛA:AÜÛAt"6AàÛBŽ€€€€‚€€€7 AÖ)7 AÐ)7 A: AëÚ,AH@AèÚ(AàÚ(k õ”!~#A0k"$@ E@@A€\\"AèÚ("AÿÿÿÿqAkA\nAëÚ,"AH""M@AàÚ(AàÚ !@  @ A€ ü\n AëÚ- Av ÀAH@AäÚ 6  AëÚ Aÿq:  jA:  AàÚ   kAäÚ( "A  A€x AàÚAàÚ(AëÚ,AN  A:,  AG:/  AG:.  AG:-  AG:+  AG:*  AG:)  AG:(  AG:\'A$t"A6 B7 B7 B7 B7 A j" 6 ! \\"A÷ÿÿÿO\r@@ A O@ Ar"Ajt!  Aÿÿÿÿk6  6  6   : A j! E\r E\r  ü\n  jA: Aj! A\'j!#AÐk"$@ A j"( , " AH"E@A<t"B7 Aì6 B7 B7 B7 B7$ B74 B€€€ü7,  6  A j6  (! AéOA4 Aèn" A4OA jA !A<t" B7 Aì6 B7 B7 B7 B7$ B74 B€€€ü7,  A j6 (!  6@ E\r (" Ak6 \r (( r Aj! ("\n! ( " \nG@@@ Ak(" E\r ("Ak6 \r (( r \n Ak" G\r (!  \n6 @A€  A€O" ( kAuM\r At"t! \n k"\n@ \nü\n   j6  \n j6  6 E\r k !@@@@ (" ("\nI@ (6 ("6 @  (Aj6 Aj!  ("k" Au"Aj" A€€€€O\rAÿÿÿÿ \n k"\nAu"  K \nAøÿÿÿO" A€€€€O\r At"\nt" j" (6 ("6  \nj!\n   (Aj6 ( ( ("k" Au  Atk! @   ü\n  \n6  Aj" 6  6 E\r k  6    Aj! @ ,AH@ (A: A6  A: A: A€z (" (  , AH6 -! -! -! -! -! -! -!\r -! -! B7( A6$ A6 A6 A6 A6 A6  A tAìžAà– r \rAtr Atr Atr Atr Atr Atr Atr6 (  , "AH"! ( ! !\n#A€k" $@ A j"(@A! ("E\rA›    A4jAAüü 6 6 )7 )7 )7 )7$ ( 6, \n60 AA ("Aq6œ A„j"AA€ü A;ã A:® A;à A:ß A: A;¿ A:ª A:¥ A:„ A€„q@ A:‚ A€€q@ A:â A€ q@ A:¨ A€€€q@ A:Á A€€€q@ A:¯ Aq@ A:Ä Aq@ A:¾ A€q@ A:² A€Âq@ A:€ Aq@A!@ A G A GqE@ jA: Ar"AýqA F@  jA: Aj"A€G\r A E\rA  jAk-"A\rF\r A\nF ! A6` A 6D 64 A€€  A€€OAt6X A„jAÿAÔü B7ä B7Ü@AA \n ("E@ AÌj!" A°jAr!# Aüj!$ AèjAr!% A°j!\rAè! A!@@ \r!@@@@ (" K@ B7ø B7ð B7èA! A°jAA \r A°jF"j \r \rF"!\r (¨!& (!@@ j-"A G A Gq\r A|qAj Aj A F! Aj" G\r ! A°jA,A j Aj " 6 A°jA$A j A j " 6A! A°jA A j Aj " A6@ (”"AL\r (œ! (! !\n@@  Alj"-A>F@ \n O\r O\r j-A>G\r Aj"!@ Aj" O\r@ j-"\nA G \nA Gq\r A|qAj Aj \nA F! Aj" G\r !   kAkA  G"\n6  6 !  \n ( "I\r  \n k"\n6 ! Aj" G\r ! ! 6ä@@ O\r j-A\nk  L\r (!@  Alj-A>F\r Aj" G\r ! " #  Aj !A!\nA!A! !@A k!A k! („"\' (üjAk!( (¬E! (!! ( !) (œ! (¤!@@ ("AG@ !   6@  ("M@ !  !@ O\r  ( j-!@  j- AÿqG\r Aj" G\r ! @  k )I\r@  O\r@@  j-A k Aj" G\r ! 6ä \rA6  6ä  F@   (k"A M6 \rA6  (! @@@@ AG\r AL\r  L\rA! A6¤  O\r  j"-A\nk @ Aj  Aäj+AL\r A6¤ AþÿÿÿqAG\r \rA6 A6 ! \rA6  @ AG\r  (”G\r \rA6  (" (œk"A O6  \rA6@@ AL"\r G\r ( AljAk-"A>G6¨  A6¨ @ ! ( AljAk-! AÿqA>F@ !  G@ !  (€\r („"A H\r (ü jAk-AG\r A6¬  @ Aq@ !    AL\r  (” G\r  ! Alj"Ak-A>F\r  G\r  (€\r  \'A H\r  (-AG\r  6A AF\r   A$k(k"A M6 Ak ! A6¬ A6¨@ (" O\r@ AG\r@ -"A-k  G\r@@ Aj" O\r@  j-F@  Aj"K\r  @@ j-A k Aj" G\r ! 6ä \rA6 AA A=F6   \nI\r -"E\rA­ ÀAPE\rA! Aj"\n O\r@@@  \nj-" AÿqF"\r A F\r A G\r j! \nAj"\n G\r !\n AI\r  AI\r A\nk @@@  L\r G\r@ Aj   Aàj Aèj,E\r -è"A>F\r ! Alj"-G\r (ð" ( K\r (ô" k j" !@ (à" O\r@ j-"A G A Gq\r A|qAj Aj A F! Aj" G\r 6ä   k6  6 !  6ä   k" 6  6 O\r@ j-A\nk M@ j"6ô A6  Aj"6ô  Ak6  ! @  O@ (AF@ !  \rA6   k6 A6 ! \n Aj   Aäj Aèj,! (!@@@@@ @ (ä!@ AG\r  G\r@@ O\r j-"A\rF\r -è! A\nG\r AÿqA>F\r  A>! -èA>G\r Aÿq"A.G A)Gq\r (ìAG\r (ô" (ðk j"!@ O\r@ j-"A G A Gq\r A|qAj Aj A F! Aj" G\r ! 6ä   k"6  6  ,è6@@@ O\r j-A\nk Aj6ô   M@  j6ô A6  Aj6ô  Ak6 E@ Aj j-\r (”! @ (˜" J@ (!  A Av j AL"6˜ ( All"E@ (("E\rAõ (0   6 (”! Aè  F! Aj! Aj6”  Alj" )ø7  )ð7  )è7 (”! (! (! ! \n A F  Fq\r (ä! ! O@ !  @ j"\n-"A#G@ ! AþF\r AàF\r !  Ak"\nF\rA!  Aj"j-A#F\r  @@  j- G\r Aj" G\r !  k"AI@ !  6 @@@  O\r@  j-A G\r Aj" G\r   O\r@@  j-"A\nk @ AàG\r \n-AàG\r !  Aj" G\r ! 6ä \rA6 A6 A6 \r \rA 6  \nF\rA!  Aj"j-A#G\r  \nF\rA!  Aj"j-A#G\r  \nF\rA!  Aj"j-A#G\r  \nF\rA!  Aj"j-A#G\r  \nF\rA!  Aj"j-A#G\r  \nF\rA! Aj!   k! ! AJ@ !  @  O"\n\r (Aq\r  j-A k"AK@ !  A tA“€€q\r !  @ \n\r@  j-"A G A Gq\r Aj" G\r !  6 6ä \rA6  6 @@@@@  O\r  j-AF\r Aj"\n O\r A/G\r \n j-A>F\r  AjM@A!  A! AA   A j>E\rA! ( "\n O\r (!@@  \nj-"A k"AK\rA tA€€qE\r \nAj"\n G\r  AAA A\nF A\rF! Aj$ 6¤@  (AG\r A6¤ ("A€qE\r (AG\r  (O\r ( j-"A-k Aj  Aäj+ F@ A6¤ A6 \rA6 AüG\r  (”G\r (€"E\r (AG\r Aäj! Aàj!A!A!@ Aj"(" M\r (" j-AüG\rA! Aj" O\r@  j-A k"\nAK\rA \ntA€€qE\r Aj" G\r ! @@@@  I@  ( j-A:Fj!  O\r ("\n j-A-G\r@@@  \nj-"A-G\r Aj" G\r Aj!  A! Aj!@  A:Fj" O\r@@  \nj-"A k"AK\rA tA€€qE\r  Aj"G\r  AüG\rA!A! Aj" O\r@  \nj-A k"AK\rA tA€€qE\r Aj" I\r !   O\r@  \nj-A\nk E\r  ! E\r  6  6A  A E\r  (à6 \rA\n6 \rA6 (”"  F  (AF! A€qE\r jAL\r ( Alj"Ak-"E\r A?K\rB ­†B€€€€ÀƒP\r@ (ä" ("\n Aj"  \nK"O\r (!@ j-"A G A Gq\r Aj" G\r ! Aj" \nO\r (" j-AÛG\r  Aj"j,"E\rAÓ APE\r  j-AÝG\r \n Aj"G@ j-A k"AK\r A tA“€€qE\r Ak % " -Ar: Ak $  6@ ("O\r (!@ j-A k"AK\rA tA€€qE\r Aj" G\r ! 6ä  6  Aj"6ô  6  6Aè!A! ! ! Aj.A! Aj A@k/\r -Aq@ Aj AÜj/\r AjA-\r Aj0\rA!#Ak" $ A6$ Aj"\rA6@ \r(€AJ@ Aøj!@@@@@@ \r(ø j" ("AÿqAk AsA\nvAq6 /:  (6 (AsA\nvAq6 /:  AÿÿK6 /: (6  A6 /At(€\\"6 /! 6 At(€6 Aj6 A$j6 @@ ("A€q@@ A€qE\r Aÿq A j \r(, \r("@ \r($"E\rA¿ \r(,   ("Aÿq"AK\rA tAŽ€qE\r \r \r(Ak6 (! A€qE\r Aÿq A j \r(, \r("@ \r($"E\rAš \r(,   @ ("AÿqAk \r(Œ \r(Alj" -Ar: \r \r(Aj6  B7` B7X B7P B7H B7@ B78 B70 B7(@ ("AÿqA\nG\r A€€„I\r ("A€ Av"nM\r Aq! Aj!A!\nA!@ "AO@ A|q!A!@  Atj"( j ( j (j (j ( ( ( (jjjk! Aj! Aj" G\r E\r @  Atj"( j (k! Aj! \nAj"\n G\r  n AvO\r \r($"A¸ \r(,  (  A€~qA r"6 A! A6ˆ B7€ B7x B7p B7h \r("@ \r(Œ AljAk-As! A!@@@@@@@ AÿqAk Av6h  A€€I\r \r("\n ("j-! ( !@@@  \r("O\r@  \nj- AÿqG\r Aj" G\r  M\r@  \nj-A G\r Aj" G\r ! @  M\r@  \njAk-A G\r Ak" K\r ! A! \r  \nj  kA Aèj AÈj9\r \r(! !\n@  M\r@  \nj-A k"AMAA tA€€q\r \nAj"\n G\r !\n \r  j \n kA  A(j9\r :ˆ (!A!  A6l Av6h (Ak6p  Av6h @@@@@@@  Aÿq"A FqE@  Aèj \r(, \r("\r (! AÿqAk \r($"E\rAš \r(,   (!@ AÿÿM@ E\r Aj!@ ( (F@ A j! Ak"\r  @  A lj"A k( Ak(G\r Ak"\r  Ak"E\r Aj! \rA  :"E\r  \rA Aj (:"E\r  (!@@ Av"Atj"E@A! \r($"E\rAä \r(,  k  @ (! ("! ! !@ !@ M\r \r(!@  j-A-F\r Aj" G\r ! A!  K@ \r( jAk-A:F! @ M\r \r(!@@  j-"\nA-G\r Aj" G\r !  Ar  \nA:F!  At( 96 Ak! Aj! AJ\r A A \r(, \r("@ \r($"E\rAš \r(,  k  \rA ( (  ;"\rA A \r(, \r("@ \r($"E\rA¿ \r(,  k  AI\r@A A \r(, \r("E@ Aj!A!  \r($"E\rAš \r(,  k  @ \rA  Atj"( (  ;"\r Aj" G\r A A \r(, \r("E\r \r($"E\rA¿ \r(,  k  k  \r Aj (<"\r A!  -"A Fq\r  Aèj \r(, \r("E\r \r($"@A¿ \r(,  ! \r (X@ (Hk (Lk (Pk (8E\r ((k (,k (0k \r (! -AkAM@ A l j!  At j!  \r(Œ \r(Alj" -Aþq A\nvAqr: \r \r(Aj6 Aj" \r(€H\r \rA6€A! Aj$ "\r -Aq@A!A!#A@j"\n$@ Aj"(`"E\r (pE\r (X AAR@@AA (, ("E@ (`E\r \nA0j!  ($"E\rAš (,   @ (X Alj"( E\r \nB7 \nB7 \nB7 \nB7 B7 B7 \n ( 6( \n (6,@ ( (A  \nAj9@A!  A \nA(j (, ("@ ($"E\rAš (,   ( (<"\rA \nA(j (, ("E@A!  ($"E\rA¿ (,  \n(@ \n(k \n( k \n(k \r Aj" (`I\r A!AA (, ("E\r ($"@A¿ (,  ! \nA@k$ "\r A!AA (0 ("E\r (("@A¿ (0  !  \n6ä \rA6 !  ! !  A6¨ ! @ (ä"Aj" ("O\r (!@@ j"-A\nk @ -A\nk @ -A\nk @  j-A\nk Aj! Aj!  I\r @ I@ (!@A!@ j-A\nk Aj" G\r ! A! A°jA(A j Aj "\n 6 " \r("AG\r@@ ("M\r (!@  jAk-"A G A Gq\r Ak" K\r  @  O\r (!@  jAk-A#G\r Ak" K\r   F\r ( jAk-"A F@ !  A F@ !  ! -AqE\r \n 6  !@ AkAI\r  ("M\r (!@  jAk-"A G A Gq\r \n Ak"6  K\r @ ( j-A\rFj! I@ ( j-A\nFj! @ &E\r E\r  j"AL\r ( Alj"Ak-A>F\r (ü Ak(j" (A€r6 @ \r  j" (”N\r Aj -\r AJ@ AjA Al" (j"(" -Aq ( j,A A1\r AjA (ü" -éAq" ( j,A A1\r ( j" -Aýq r: ( j 6 @ (”!@ -AqE\r ( Alj"Ak-A>G\r \r(AG\r \n(" ("k"AkA K\r (" j"-AÛG\r -A!G\r  jAk-AÝG\r Ak! Aj!A!@@@@ Ak @  j-"A k  AákAÿqAIAÿq -¹"A k  AákAÿqAIAÿqG\r Aj" G\r A  @  j-"A k  AákAÿqAIAÿq -Î "A k  AákAÿqAIAÿqG@ A\nk Aj" G\r A  A!@  j-"A k  AákAÿqAIAÿq -ú "A k  AákAÿqAIAÿqG@ A\nG\r  Aj" G\r A  A!@  j-"A k  AákAÿqAIAÿq -‡"A k  AákAÿqAIAÿqG@ A\nG\r -"A k  AákAÿqAIAÿqAÃG\r -"A k  AákAÿqAIAÿqAÁG\r -"A k  AákAÿqAIAÿqAÕG\r -"A k  AákAÿqAIAÿqAÔG\r -"A k  AákAÿqAIAÿqAÉG\r -"A k  AákAÿqAIAÿqAÏG\r -"A k  AákAÿqAIAÿqAÎG\rA  Aj" G\r A ! Ak" -Ar: ( (”AljAk" -AÇq r: \rA6 (”!  k!@A!@@A ( Alj"-A)kt"AqE@ A!qE\rA! Aj.  („6 Aj  ( ,A1\r AjA (" -Aq ( j,A A1\r  AjAA -"AqA AvAqA1\r Aj" (”H\r @ \r(E@ Aj.@A!  A!Aè! -AÀqE\r ( \n(I\r (ŒAj6Œ  (Œ@@ („"Aj" (ˆ"J@ A€ Av j AL"6ˆ (ü l"E@A! (("E\rAõ (0   (€"@   (ükj6€ 6ü („"Aj6„  6„ (ü"\rA!   j"A; (Œ! A6  AtAr6 A6Œ @ (E\r Aj.E\rA!  @@@@ \r("Ak\n A! Aj.\r („"Aj" (ˆ"J@ A€ Av j AL"6ˆ (ü l"E@ (("E\r\nAõ (0  \n (€"@   (ükj6€ („"Aj6„ 6ü  j  6„ (ü"E\r  j " \r(AÃÌj-"; (! A6   Atr6 6€ Aj \r2\r Aj.\rA!Aè!  (€A: (€ /; (€" (A€r6A! Aj \r2\r Aj.\rA! (€E@Aè!  \rA6 \r!  (€A\n: (€ /; A 6AA Aj \r2!  @  (F\r Aj.E\rA!  @ (€\r \r! @ Aj"(€"Aj"\n („"J@ A€ Av j AL"6„ (ø l"E@A ($"E\rAõ (, A  (ü"\n@   \n (økj6ü  6ø  (€"\nAj6€  \nj   \n6€ (ø"E\r  j " \r(AÃÌj-"\n; \r(! A6  \n Atr6  6üA  A E\rA!  Aj \r2! A! E\r  A!  (("E\rAš \n  (P"@ (T"A!@@ (P Atj("E\r (@" M@   (D (HljI\r k (T! Aj" I\r (P k (H@A!@ (@ Atj"-"Aq (k -  Aq@ ( k Aj" (HI\r (@k (l"@ (p"A!@@ (l Atj("E\r (\\" M@   (` (dljI\r k (p! Aj" I\r (l k (d@A!@ (\\ Alj(k Aj" (dI\r (\\k (8k (xk (ük (k A€j$ @A<t"B7 Aì6 B7 B7 B7 B7$ B74 B€€€ü7,  6  A j6  (@ (("E\r ((" ($"G A$j!A!\r@@@  \rAt"\nj("(AF@ ($" (("G\r \rAj!\r   k"Au!@@ ((AF\rA! AG@@ Aj!  Atj"((AF@  O\r Ak(!  Atj(! \r \r  "G\r A! A68 B70A!  A! A68 B70 A6L B7D  A0j6@  AÄj6<@@@@@@  At"j"(" (AG\r  Ak(A !  Aj"K@  Atj( rAG\r AF\r @ Aj" O\r -"A k  AákAÿqAIAÿqAÓG\r -"A k  AákAÿqAIAÿqAÃG\r -"A k  AákAÿqAIAÿqAÒG\r -"A k  AákAÿqAIAÿqAÉG\r -"A k  AákAÿqAIAÿqAÐG\r -"A k  AákAÿqAIAÿqAÔG\r  j-A>F\r @ Aj" O\r -"A k  AákAÿqAIAÿqAÓG\r -"A k  AákAÿqAIAÿqAÔG\r -"A k  AákAÿqAIAÿqAÙG\r -"A k  AákAÿqAIAÿqAÌG\r -"A k  AákAÿqAIAÿqAÅG\r  j-A>F\r A\nj" O\r -"A k AákAÿqAIAÿqAÔG\r -"A k AákAÿqAIAÿqAÅG\r -"A k AákAÿqAIAÿqAØG\r -"A k AákAÿqAIAÿqAÔG\r -"A k AákAÿqAIAÿqAÁG\r -"A k AákAÿqAIAÿqAÒG\r -"A k AákAÿqAIAÿqAÅG\r - "A k AákAÿqAIAÿqAÁG\r  j-A>F\r\r Aj" G\r !  6A Aj" O\r Ak! (!@@  j"-A\nk\n\n /A­Ús -A>srE\r Aj! Aj!  I\r !  Aj" O\r Ak! (!@@  j"-A\nk /A¿üF\r Aj! Aj!  I\r !  Aj" O\r Ak! (!@@@  j-"A\nk  A>F\r Aj! Aj!  I\r !  Aj" O\r Ak! (!@@  j"-A\nk /Aݺs -A>srE\r Aj! Aj!  I\r !  @@  O\rA! ( j-A\nk  6 ( !   6A  6A  6A  6A  6A  Aj6A Å@  ("O\r  (˜O\r @ (" j-"E\r A>F@ A>:  6  -Aüq: Aj! Aj  A?K\rB ­†B€€€€€ ƒP\r  Aj"K@  j-A k"AK\rA tA“€€qE\r  :  6  -Aüq: Aj  A! A6  A j"  I"\nO\rA! !@@ j-" A0kAÿqA K\r  A\nljA0k"6 Aj" \nG\r \n! M\r O\r@ j-" A)k  Aj"K@  j-A k"AK\rA tA“€€qE\r  :  6  -Aüq:  k jAj 6  6A!  ç  ("H@@A!@@@A (Œ Alj"Ak"-A)kt"AqE@ A!qE\rA! Ak(!A! Ak-Aq@ ( j,! A! A  A1\r A ,A1\r  AA Ak-"AqA AvAqA1E\rA!  (Ak"6  H\r A Ú#A0k"$@ (ü"E\r@@@ ("AÿqAk A€qE\r (" (O\r ( j-AÛG\r@ ("E\r Aj! AG\r !  @ \r@ A/G\r Aj" O\r \n j-A>F\r AL\r@ AßqAÁkAÿqAI\r AßF\r A:G\r  Aj"M@A!  @@@ \nj,"A0kAÿqA\nI\r A_qAÁkAÿqAI\r E@A!  A  APE\r A!  Aj"G\r  A!  A! @@ Ak A=G\r Aj!A!  A+!@@@@ A"k E\r Aá AP\r A\rF\r A)!  A*! Aj! I\r A! E\r \rF\rA  A)FA !  Aj" Atj"(! (" I\r   M@A A!  Aj6 „#Ak"$@  O\r@@@ j"  k A j4"AÿK@A!A!@@@  jAm"AtA j("\nAu j"AtA j(Aÿÿÿq K@ Ak!   \nAvAq j"AtA j(AÿÿÿqM\r Aj!  L\r  AH\r  A F\r A F\r A kAI\r -A\nk ( j" I\r Aj$  à@@@ AÿK@A­!@@@  jAm"AtAÀj("Au j"AtAÀj("Aÿÿÿq K@ Ak!  AvAq j"AtAÀj(AÿÿÿqM\r Aj!  N\r  AH\rAÐ8!  A6  A r AÁkAI6 A!A4!@@@  jAm"AtAÀ1j("Au j"AtAÀ1j("Aÿÿÿq M@ AvAq j"AtAÀ1j(Aÿÿÿq O@ AH\rAà8!  Aj!  Ak!  N\r A!A!@@@  jAm"AtAÐ6j("Au j"AtAÐ6j("Aÿÿÿq M@ AvAq j"AtAÐ6j(Aÿÿÿq O@ AH\rAð8!  Aj!  Ak!  N\r A6  6  ( ( " lAtj! At"@   ü\n  6 F\r ( Aÿÿÿq"AjF@  sAsAq j6  ( kj6 õ #A k"$ B7 B7 B7 B7 A ?! A ?! @@@  K@   M\r @ \nE@   AjC!A! AqE@   C! A!  Atj( Aj Atj(k"\r Aj" ( " I! Aj" (" I!\n  K\r  I\r  K\r  I\r A! A j$  iA!@ ("(" ("("I\rA!  K\r ( ( ( (A"\rA! (" ("I\r K!  ‰#Ak"$@@@  O\r j  k A j4! ( j! AÿK@A!@@@  jAm"AtA j("\nAu j" AtA j(Aÿÿÿq K@ Ak!   \nAvAq j"AtA j(AÿÿÿqM\r Aj!  L\r  AN\r  A F\r A F\r A kAO\r A6 A 6  ?!   @ Aj$  D ("(" ("("I@A  K@A ( ( ( (A ›”#A0k"$ A6x#Ak"$ AjAA€ü @@ E\r Ak! A€j!  AtjAk!@  Atj"(!@ !@ !@ Aj" ("O@ !  (! @  j"-j-@ !  -j-@ !  -j-@ !   j-j-@ !  Aj! Aj"!  K\r @  K@ (!@  j"-" j-\r Aj" G\r Aj" I\r  @AA@@@@@@ AÜF@A! Aj" (O\r@  j-"A!kAÿqAI\r@ AÿqA\nku Aj I\r Aj! @@ (x" (|"N@ AÀ Av j AL"6| (t All"\rA! ($" E\rAõ (,   Aj6x (t"\rA!  6t (x"Aj6x  Alj"AÜ ; B7  Aj"6  6 A!@@@@@@@@@@@@ A!k\\ \r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\n\r \r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r Aj"\r!\n@  \rM\r@  \nj- G\r \nAj"\n I\r !\n A!A!A!  (F\r N"AÿM\rA!A!@@@@  jAm" AtA j("Au j"AtA j(Aÿÿÿq K@ Ak!   AvAq j"AtA j(AÿÿÿqM\r Aj!  N\r  A! AN\r A!Aä!@@@  jAm" AtA°9j("Au j"AtA°9j(Aÿÿÿq K@ Ak!   AvAq j"AtA°9j(AÿÿÿqM\r Aj!  N\r A! AN   k! !@@  j-" AàG\r Aj" G\r !A  A F ! !  k"A K\r At j( "\r  AtjAk(O\rA!A!@ E@ ! !\n  !\n \r " I\r @@@@ \nO\r@  j-"\rA G@ \rAàF\rA! Aj" \nG\r A! \n  !\r \nO@A! !  @  \rj-AàG"@ ! \r!  \rAj"\r \nG\r ! \n! @  k"\rF@A!\n  Atj"("\r I@  jAk-A F!\n As  Gq\r \r \rF \nrE\r E\r Aj  @ F\rA! \rAK\r \rAt jA j"\r \r("\r \rK6 \r  Aj"M@A!   Atj"\n(! \n(!\n  ( ! \n@ Ak!  Ak(" ("O\r@  j-"A G A Gq\r Aj" G\r ! @@ (x" (|"N@ AÀ Av j AL"6| (t All"\rA! ($" E\rAõ (,   Aj6x (t"\rA!  6t (x"Aj6x  Alj"Aà; B7  6  6@@ (x" (|"N@ AÀ Av j AL"6| (t All"\rA! ($" E\rAõ (,   Aj6x (t"\rA!  6t (x"Aj6x  Alj"Aà; B7  6  6 (t (x"Alj"Ak" Ak6 A(k" Ak6  -Ar:  -Ar:A! ! ! ! (M\r@@@   jAv"Atj"( K@ E\r  AtjAk( I\r Ak!  (K\r ! !  Aj! @@ (x" (|"N@ AÀ Av j AL"6| (t All"\rA! ($" E\rAõ (,   Aj6x (t"\rA!  6t (x"Aj6x  Alj"A¦; B7  Aj"6  6  (x"AL\r (t" AljAk-A&G\r (|" L@ AÀ Av j AL"6|  All"E@A! ($" E\rAõ (,   6t (x! Aj6x  Alj"A»; B7  Aj6  6  ("\n - AÀq\r\n   k"  \n A j>\r (" AjM\r -A!G\r  Aj"j-A-G\r -A-G\r A! (è" K  \nAkOq\r @ Aj" \n \nI"\rM@  j" /A­Ús -A>srE\r\r@@ Aj! Aj" \rK\r " j" /A­Ús -A>sr\r  !  \nI  Aj" Kq@  Atj"(! (!  6è (! A! -AqE\r Aj" O\r  j-AüG\r@@ (x" (|"N@ AÀ Av j AL"6| (t All"\rA! ($" E\rAõ (,   Aj6x (t"\rA!  6t (x"Aj6x  Alj"Aü; B7  Aj"6  6  ("Aj K\r  Ak"\rj"/A÷îs -A÷sr\r @  \rF\r \rN"AÿK@A!A!@@@@  jAm" AtA j("\nAu j"AtA j(Aÿÿÿq K@ Ak!   \nAvAq j"AtA j(AÿÿÿqM\r Aj!  N\r  AN\r A!Aä!@@@  jAm" AtA°9j("\nAu j"AtA°9j(Aÿÿÿq K@ Ak!   \nAvAq j"AtA°9j(AÿÿÿqM\r Aj!  N\r  AH\r\r  A F\r A F\r A\rkA}K\r A!kAI\r A:kAI\r AÛkAI\r AÿG AúKqE\r @@ (x" (|"N@ AÀ Av j AL"6| (t All"\rA! ($" E\rAõ (,   Aj6x (t"\rA!  6t (x"Aj6x  Alj"A®; B7  Aj"6  \r6@@ (x" (|"N@ AÀ Av j AL"6| (t All"\rA! ($" E\rAõ (,   Aj6x (t"\rA!  6t (x"Aj6x  Alj" (6 (! AÄ; B7  6  Aj!@@ (" Aj K\r  Ak"\nj(AèèуG\r  M\r /A¯ÞF\r @ Aj K\r  Ak"\nj"\r(Aèèуs \r-Aósr\r  M\r /A¯ÞF\r Aj K\r  Ak"\nj"/Aæès -Aðsr\r  M\r /A¯ÞG\r @@ (x" (|"N@ AÀ Av j AL"6| (t All"\rA! ($" E\rAõ (,   Aj6x (t"\rA!  6t (x"Aj6x  Alj"Aº; B7  6  \n6@@ (x" (|"N@ AÀ Av j AL"6| (t All"\rA! ($" E\rAõ (,   Aj6x (t"\rA!  6t (x"Aj6x  Alj" (6 (! AÄ; B7  6 Aj!  (Aj K\r @ Ak-"AßqAÁkAÿqAO@ Aj O\r A0kAÿqA\nO\r  Aj O\r\n  Aj"j-"A0kAÿqA\nO@ A_qAÁkAÿqAK\r\n @@ (x" (|"N@ AÀ Av j AL"6| (t All"\rA! ($" E\rAõ (,   Aj6x (t"\rA!  6t (x"Aj6x  Alj"AÀ; B7  6  6@@ (x" (|"N@ AÀ Av j AL"6| (t All"\rA! ($" E\rAõ (,   Aj6x (t"\rA!  6t (x"Aj6x  Alj" (6 (! AÄ; B7  6 Aj!  @@ (x" (|"N@ AÀ Av j AL"6| (t All"\rA! ($" E\rAõ (,   Aj6x (t"\rA!  6t (x"Aj6x  Alj"AÝ; B7  Aj"6  6 \r @@ (x" (|"N@ AÀ Av j AL"6| (t All"\rA! ($" E\rAõ (,   Aj6x (t"\rA!  6t (x"Aj6x  Alj" 6A!A  Aj" O\r  j-AÛG\r@@ (x" (|"N@ AÀ Av j AL"6| (t All"\rA! ($" E\rAõ (,   Aj6x (t"\rA!  6t (x"Aj6x  Alj" 6A!!A !  :  : B7   j"6@@ (x" (|"N@ AÀ Av j AL"6| (t All"\rA! ($" E\rAõ (,   Aj6x (t"\rA!  6t (x"Aj6x  Alj"AÄ; B7  6  6@@ (x" (|"N@ AÀ Av j AL"6| (t All"\rA! ($" E\rAõ (,   Aj6x (t"\rA!  6t (x"Aj6x  Alj"AÄ; B7  6  6 \n @@ E@  -\rA qAvq\r  E\r @@ (x" (|"N@ AÀ Av j AL"6| (t All"\rA! ($" E\rAõ (,   Aj6x (t"\rA!  6t (x"Aj6x  Alj"A:  : B7  Aj"6  6 \n @@@@@@@@@@@AA@@AA@@@@@@@@@@@@@@ >\r"""""""" " """"""""""""""""""" """""""""""""""""""""""""" AÞF\r AþG\r!A! Aj"\n!@  \nM"\r@  j-AþG" \r Aj" I\r !  k"AG\r ( "A€€qE\r \rA! A!  \nj ( \nkA4"AÿK\r A F\r A F\r A kAM\rA  A! Aj" I\r -AqE\r Aj"!@  M\r@@  j-AÞG\r Aj" I\r ! !  kAG\r%A! A!  j ( kA4"AÿM@ A F\r A F\r A kAM\rA  @@@  jAm"AtA j("\rAu j"\nAtA j(Aÿÿÿq K@ \nAk!   \rAvAq j"AtA j(AÿÿÿqM\r Aj!  N\r A  \nAN\rA  A !  (F\r N"AÿM\rA!A!@@@  jAm" AtA j("\rAu j"\nAtA j(Aÿÿÿq K@ \nAk!   \rAvAq j"AtA j(AÿÿÿqM\r Aj!  N\r !  \nAN\r !  -A qE\r Aj" O\r@  j" -A=F@  Aj"K\r  !  kAG\r"A!A!AA ( kA4"AÿM@A! A F\r A F\r A kAI  @@@  jAm" AtA j("\rAu j"\nAtA j(Aÿÿÿq K@ \nAk!   \rAvAq j"AtA j(AÿÿÿqM\r Aj!  N\r A!\n \nAN !  -A€qE\r Aj" O\r@  j" -A+F@  Aj"K\r  !  kAG\r!A!A!AA ( kA4"AÿM@A! A F\r A F\r A kAI  @@@  jAm" AtA j("\rAu j"\nAtA j(Aÿÿÿq K@ \nAk!   \rAvAq j"AtA j(AÿÿÿqM\r Aj!  N\r A!\n \nAN !  @@@  jAm"AtA j("Au j"\rAtA j(Aÿÿÿq K@ \rAk!   AvAq j"AtA j(AÿÿÿqM\r Aj!  N\r A  \rAN\rA  A !  (F\r\r N"AÿM\r A!A!@@@  jAm" AtA j("Au j"\rAtA j(Aÿÿÿq K@ \rAk!   AvAq j"AtA j(AÿÿÿqM\r Aj!  N\r !  \rAN\r\r !  ! AK\r ( ! ! A€qE\rA!  (M\r N"AÿM\rA!\nA!@@@@  \njAm"\rAtA j(" Au \rj"AtA j(Aÿÿÿq K@ Ak!   AvAq \rj"\nAtA j(AÿÿÿqM\r \nAj!\n  \nN\r  AN\r\n A!\nAä!@@@  \njAm"\rAtA°9j(" Au \rj"AtA°9j(Aÿÿÿq K@ Ak!   AvAq \rj"\nAtA°9j(AÿÿÿqM\r \nAj!\n  \nN\r A! AN  @  j-A$F@  Aj"K\r  A! !  kAK\rA!  (M\r N"AÿM\rA!A! @@@@  jAm"\nAtA j("Au \nj"\rAtA j(Aÿÿÿq K@ \rAk!   AvAq \nj"AtA j(AÿÿÿqM\r Aj!  L\r  \rAN\r A!Aä! @@@  jAm"\nAtA°9j("Au \nj"\rAtA°9j(Aÿÿÿq K@ \rAk!   AvAq \nj"AtA°9j(AÿÿÿqM\r Aj!  L\r A!\r \rAN  @ Aj" O\r@  j-A k"AK\rA tA€€qE\r Aj" I\r ! A F@ !  kAI\r @@ (x" (|"N@ AÀ Av j AL"6| (t All"\rA! ($" E\r Aõ (,  Aj6x (t"\rA!  6t (x"Aj6x  Alj"A:  : B7  6  6  @@ (x" (|"N@ AÀ Av j AL"6| (t All"\rA! ($" E\rAõ (,   Aj6x (t"\rA!  6t (x"Aj6x  Alj"A€ ; B7  Aj"6  6  A F\r A F\r A\rkA}K\r AÿG AúKq A!kAI A:kAIr AÛkAIrr ! @ E\rA! A!@  j" ( k" A4"AÿM@ A F\r A F\r A kAO\r  @@@  jAm"AtA j("\rAu j"\nAtA j(Aÿÿÿq K@ \nAk!   \rAvAq j"AtA j(AÿÿÿqM\r Aj!  N\r  \nAN\r A!Aä!  A4"AÿM@ AÿG AúKq A!kAI A:kAIr AÛkAIrr  @@@  jAm" AtA°9j("\rAu j"\nAtA°9j(Aÿÿÿq K@ \nAk!   \rAvAq j"AtA°9j(AÿÿÿqM\r Aj!  N\r A!\n \nAN ! !  Aq "E\r @@ (x" (|"N@ AÀ Av j AL"6| (t All"\rA! ($" E\rAõ (,   Aj6x (t"\rA!  6t (x"Aj6x  Alj" : A$: B7  6  6  A F\r A F\r A\rkA}K\r AÿG AúKq A!kAI A:kAIr AÛkAIrr ! @ E\rA! A!@  j" ( k" A4"AÿM@ A F\r A F\r A kAO\r  @@@  jAm"AtA j("\rAu j"\nAtA j(Aÿÿÿq K@ \nAk!   \rAvAq j"AtA j(AÿÿÿqM\r Aj!  N\r  \nAN\r A!Aä!  A4"AÿM@ AÿG AúKq A!kAI A:kAIr AÛkAIrr  @@@  jAm" AtA°9j("\rAu j"\nAtA°9j(Aÿÿÿq K@ \nAk!   \rAvAq j"AtA°9j(AÿÿÿqM\r Aj!  N\r A!\n \nAN ! !  Aq "E\r @@ (x" (|"N@ AÀ Av j AL"6| (t All"\rA! ($" E\rAõ (,   Aj6x (t"\rA!  6t (x"Aj6x  Alj" : Aþ: B7  6  6  A F\r A F\r A kAM\r !  A! ! AqE\r @@ (x" (|" N@ AÀ Av j AL"6| (t All" \rA! ($" E\rAõ (,   Aj6x (t" \rA!  6t (x"Aj6x Alj" : Aþ: B7  \n6  6  A! !  kAG\r @@  (F\r N"AÿK@A!A!@@@  jAm" AtA j("\rAu j"\nAtA j(Aÿÿÿq K@ \nAk!   \rAvAq j"AtA j(AÿÿÿqM\r Aj!  N\r !  \nAN\r !  A F\r A F\r A kAM\r !  A! ! AqE\r @@ (x" (|" N@ AÀ Av j AL"6| (t All" \rA! ($" E\rAõ (,   Aj6x (t" \rA!  6t (x"Aj6x Alj" : A+: B7  6  6  A! !  kAG\r @@  (F\r N"AÿK@A!A!@@@  jAm" AtA j("\rAu j"\nAtA j(Aÿÿÿq K@ \nAk!   \rAvAq j"AtA j(AÿÿÿqM\r Aj!  N\r !  \nAN\r !  A F\r A F\r A kAM\r !  A! ! AqE\r @@ (x" (|" N@ AÀ Av j AL"6| (t All" \rA! ($" E\rAõ (,   Aj6x (t" \rA!  6t (x"Aj6x Alj" : A=: B7  6  6 A F\r A F\r A kAM\r !  A! ! AqE\r @@ (x" (|" N@ AÀ Av j AL"6| (t All" \rA! ($" E\rAõ (,   Aj6x (t" \rA!  6t (x"Aj6x Alj" : AÞ: B7  6  6 @ Aj" O\r -A?G\rA!@ (ì" M@ !  !  \nAkO\r  Aj" \n \nI"\rM@  j/A¿üF\r@@ Aj! Aj" \rK\r " j/A¿üG\r  !  \nI  Aj"Kq  Atj"(! (!  6ì ( ! @ M\r -A!G\r  j-AßqAÁkAÿqAK\r@ Aj" O\r@  j-AßqAÁkAÿqAK\r Aj" G\r ! A! (ð" K  \nAkOq\r Aj" \n \nI"\rM@  j-A>F\r@@ Aj! Aj" \rK\r " j-A>G\r  !  \nI  Aj" Kq  Atj"(! (!  6ð ( ! @ A j" O\r )B¼ÂìšÄ¨ªÁ… 1Bۅ„BR\rA!\r (ô" K  \nAkOq\r@ Aj" \n \nI" M@  j"/Aݺs -A>srE\r@@ Aj! Aj" K\r  "j"/Aݺs -A>sr\r  !  \nI  \rAj"\rKq@  \rAtj"(! (!  6ô ( !\n ! Aj" \nO\r@ Aj" \nO\r  j-" A0kAÿqA\nIA AßqAÁkAÿqAI E\r@  j-"A0kAÿqA\nI\r AßqAÁkAÿqAI\r A+k"AK\r AF\r Aj" \nF\r@  kA K\r  j-" A:F@  \nO\r@  j-" A k"AMAA tA€€q\r A>G@ A I\r AG\r  j-A-F\rAð! Aj !@@ (x" (|"N@ AÀ Av j AL"6| (t All"\rA! ($" E\r\rAõ (,  \r Aj6x (t"\rA! 6t (x"Aj6x  Alj" Ar: A<: B7  6  6@@ (x" (|"N@ AÀ Av j AL"6| (t All"\rA! ($" E\r\rAõ (,  \r Aj6x (t"\rA! 6t (x"Aj6x  Alj" Ar: A>: B7  6  Ak6 (t (x"Alj"A k Ak6 Ak Ak6 ! !   6 @@@ (x" (|"N@ AÀ Av j AL"6| (t All"E\r 6t (x"Aj6x  Aj6x (t"E\r  Alj"A¼(; B7  6  6@ (x" (|"N@ AÀ Av j AL"6| (t All"E\r 6t (x"Aj6x  Aj6x (t"E\r ( !  Alj"A¾0; B7  6  6 (t (x"Alj"A k Ak6 Ak Ak6A! !  (M\r@@   jAv"Atj"( K@ E@ !   AtjAk(K@ ! Ak!  ( O@ ! \n Aj!  M\r A!  ($"E\rAõ (,  A!  Aj!  A F\r A F\r A\rkA}K\r AÿG AúKq A!kAI A:kAIr AÛkAIrr "! As AßFq! @  \nF\rA!A!@  \nj" ( \nk"A4"AÿM@ A F\r A F\r A kAO\r  @@@  jAm"AtA j(" Au j"AtA j(Aÿÿÿq K@ Ak!   AvAq j"AtA j(AÿÿÿqM\r Aj!  N\r  AN\r A!Aä!AAA  A4"AÿM@ AÿG AúKq A!kAI A:kAIr AÛkAIrr  @@@  jAm"AtA°9j(" Au j"AtA°9j(Aÿÿÿq K@ Ak!   AvAq j"AtA°9j(AÿÿÿqM\r Aj!  N\r A! AN "Aq As qAq"!A  ! ! \n!  rE\r  kAp!@@ (x" (|"N@ AÀ Av j AL"6| (t All"\rA! ($" E\rAõ (,   Aj6x (t"\rA!  6t (x"Aj6x  Alj" AtA# AG  LqAA  NA AJr" AFrA@k:  : B7  \n6  6 \n \r"M\r@@@ (x" (|"N@ AÀ Av j AL"6| (t All"\rA! ($" E\rAõ (,   Aj6x (t"\rA!  6t (x"Aj6x  Alj"AÄ; B7  \r6  \r6 \rAj"\r \nI\r ! \n! @@ (x" (|"N@ AÀ Av j AL"6| (t All"\rA! ($" E\rAõ (,   Aj6x (t"\rA!  6t (x" Aj6x (!  Alj"Aÿ ; B7  6  6A! Aj$@ " \r A (xAÏAJ@ (à"AN@ Ak!\r A€j! AØj! A j!@ (t" Al"j" (! @ -"AÄF\r ( !A! A! AN@   Alj" ( Alj! Al! (! -A q@ A!: Ak"6A!!  j!  I@ ( I\r  I@ ( I\r @  I@ A!G\r  AÛG\r ( A€€ÀqE\r (" (O\r ( j-AÞG\r Aj"6 (t j"(" M\r  ( j  kK"E\r ( "E@ (pAj"6p  6  (Aj6 6 (6 -A”r:  -A˜r: (! (! (  @@@@ -\rA qE\r -AÛG\r E\r (" ("kAG\r -AÛG\r E\r ( ("kAG\r -AÝG\r  AkG\r ( ("kAG\r  (AjG\r@@ Aj" N"@ !  (t! !@@  Alj"\n-"AÄF\r AüF\r \n( kAäK\r \n-AqE\r \n( ! Aj" H\r A!\n \n  \n(" F\r  kAäK\r  I@ (!@@  j-A\nk Aj" G\r A!@   Atj"("L@ (t! @ Alj( " N\r  6  ("L@ (t! @ Alj( " N\r  6 Aj"AG\r \n@@ \n( (I@@  L\r  kAk! (t! A!  AsjAq"@@ AljAÄ; Aj! Aj" G\r AI\r@ Alj"AÄ;L AÄ;8 AÄ;$ AÄ; Aj" G\r \n \n-Ar: \n(6  @ \r  kAk! (t! A!  AsjAq"@@ AljAÄ; Aj! Aj" G\r AI\r@ Alj"AÄ;L AÄ;8 AÄ;$ AÄ; Aj" G\r  \n(6 (6  (6 (t" j" 6 j" 6  -Ar: -Ar: (! (!  Aj L (  (6  (6 (t" j" 6 j" 6  -Ar: -Ar: (! (! (  \r (!  (" ("G\r ( AjK@ -AÀq\r    ( AjM  -AÀq\r   (  AjM "AH\r E\r  (6 (t Alj(!  @  ("O\r (" j-A(G\r Aj!\nA! \r!@@@   jAv"Atj"( K@ E\r  AtjAk( I\r Ak!   (M\r Aj!  O\r A! @@ Aj"  Atj(" I@@  j-A k"AK\rA tA€€qE\r Aj" G\r !  6@  O\r  j-A\nk Aj" O\r  Atj(!  6 @  O\r  j-A)G\rA! A6 B7  6  6 Aj! A    Atj"(" Aj Aj 5E\r@   k ( Aj A j A,j A(j A$j6@ ( " j! (," F!   j"Atj(! (!   ("6(  6$A!A! @  I@@  j-"A k"AK\rA tA€€qE\r Aj" G\r Aj" O\r   Atj("j-! AÿqA)G\r  Aj" 6 ($" (("M@A! A6 B7A   k! @ A6  6   j"6A  @ j"@  Atj!A! !@   Atj("  K" KA!  "kAq"@@  ( j-: Aj! Aj! Aj" G\r  kA|M@@  ( j-:  ( j-:  ( j-:  ( j-: Aj! Aj" G\r   O\r A\n: Aj!  Aj"Atj(! ($" E\rAä (,   A6  6   k6 (! A ! (x" \nL@  6  (t! \n!@  Alj"(K@@ -AqAG\r  ( "Alj( I\r \r k  Aj" H\r  6  \nL\r  kAk! (t! A!  AsjAq"@@ \nAljAÄ; \nAj!\n Aj" G\r AI\r@ \nAlj"AÄ; AÄ;L AÄ;8 AÄ;$ \nAj"\n G\r  -AÀq\r   ( ( AjM"AH\r E\r -Ar:  -Ar: Aj" (tj (6 (t j ( 6  (tj (6( Aj! (t! (@  Alj (Ð6 6Ð  Alj (6 (! (! -!  Aj L   AÛF"!   !   !   ! ! / AŒqE\r@@ "Aj! -$"AÄG" \r  I\r À! !@@ "Ak! \r  K\r -%" AqE\r E\r ( (G\rA‡ APE\r (  (tkAmG\r Ak( (G\r AÄ:$  Aïq:% AkAÄ: Ak" -Aïq: "AN\r B7à A6¸ @A! A6Ô (x"AL\r (t! A!@@ Alj"-"Aq\r -AüG\r ( (kAG\r A6  Ar:@ (ØAH@ 6Ø  (ÜAlj 6 6Ü Aj"6Ô Aj" G\r A!  A! A (xL  A! A0j$ Þ#Aðk"$ B7h B7` B7X B7P B7H B7@ B78 B70 A6( B7 B7 B7 B7A! @    Aj AÐj9\r  A Aj A0j9\r  6( (,! @  Aj (" E@A!  ($"E\rAÒ (,    Aj (" E@A!  ($"E\rAö (,  (`@ (Pk (Tk (Xk (@@ (0k (4k (8k Aðj$ Ý@ ( " ("I@ (!  ( Av jA "At"l"E@A ($"E\rAõ (, A  6 ( Ajl"E@A ($"E\rAõ (, A  6  6 ( ! ( Atj 6  ( Atj 6  ( Aj6 A Ü Aj!@@@ Aj" O\r j-A#G\r j-A rAøG\r !@@@@ j-"A0kAÿqA\nI\r AÁkAÿqAI\r  kAK\r AákAÿqAI\r   kAK\r Aj" G\r !  F\r  kAI\r  @ Aj" O"\r j-A#G\r !@@  kAK\r j-A0kAÿqA K\r Aj" G\r !  F\r  kAI\r   M\r j-AßqAÁkAÿqAK\r  \r@@ j-"AßqAÁkAÿqAO@   kA0K\r A0kAÿqA\nI\r    kA0M\r   Aj" G\r  " kAkA.K\r  M\r j-A;G\rA!  Aj6  ³#Ak"$@@  O\r (!@  j-A k"AK\rA tA€€qE\r Aj" G\r !   O\r (!@  jAk-A k"AK\rA tA€€qE\r Ak" K\r !  6  6  6@  Aj (, ("@ ($"E\rAš (,   AjA<"\r  Aj (, ("E@A!  ($"E\rA¿ (,  Aj$  à!#A0k"\r$  H@ A¸j! A€j! \rAr! \rAr! (!@@ (t" Al" j" -"Aq@ AqE\r@ E\r ,"E\r  [\r ( !  ,"\nAÿq"E\r  \n[E\r (" I\r@@@@@@@@@@@@@@@@@ A!k^  (! Aq@ AN@  Alj" -AÀr: 6  6  AH\r  Alj"( 6¸  6 6@ (ä" AN@  Alj 6  6à 6ä A6  Aj" (xN\r  Alj"-A;G\r (  (" \rHE\r 6  6 Ar:  -Ar: 6  AqE\r \r A€A˜ \nA*Fj" A j6 AÀq"AÀF@A!   \r Aj6 A€F\rA!  Aj6A! A°A´ ( kAFj!\n@ AqE\rA! \n("AH\r@   Atj"\n("L@@  Alj( " N\r \n 6  \n("L@@  Alj( " N\r \n 6 Aj" AG\r  Alj" 6 6  -Ar: -Ar: \r AqE\r \n(6 \n 6 @ AqE\rA! (Ä"AH\r@   Atj"\n("L@@  Alj( " N\r \n 6  \n("L@@  Alj( " N\r \n 6 Aj" AG\r  Alj" 6 6  -Ar: -Ar: AqE\r (Ä6 6Ä @ AqE\r (¼"AH\rA!  Alj" ( (k ( kG\r@   Atj"\n("L@@  Alj( " N\r \n 6  \n("L@@  Alj( " N\r \n 6 Aj" AG\r @ Aj" N\r  kAk!A!  AsjAq"\n@@  AljAÄ; Aj! Aj" \nG\r AI\r@  Alj" AÄ;L AÄ;8 AÄ;$ AÄ; Aj" G\r 6 6 -Ar: -Ar: A6¼ AqE\r\n (¼6 6¼ \n  Aj"Al"j"(! (! \r 6 \r ("6, \r 6( \r 6$ \nAÀF@   \rAAAA¨ \rA(jOAL\r\n \r(!  O\r N"AÿM\rA!A!@@@  jAm" AtA j("Au j"AtA j(Aÿÿÿq K@ Ak!   AvAq j"AtA j(AÿÿÿqM\r Aj!  N\r  AN\r  ( kAG\r@ AqE\rA! (À"AH\r@   Atj"\n("L@@  Alj( " N\r \n 6  \n("L@@  Alj( " N\r \n 6 Aj" AG\r  Alj" 6 6  -Ar: -Ar: AqE\r (À6 6À  ( kAG\r@ AqE\rA! (È"AH\r@   Atj"\n("L@@  Alj( " N\r \n 6  \n("L@@  Alj( " N\r \n 6 Aj" AG\r  Alj" 6 6  -Ar: -Ar:  AqE\r (È6 6È  ( kAG\r@ AqE\rA! (Ì"AH\r@   Atj"\n("L@@  Alj( " N\r \n 6  \n("L@@  Alj( " N\r \n 6 Aj" AG\r  Alj" 6 6  -Ar: -Ar:  AqE\r (Ì6 6Ì  A!A!  A F\r A F\r A kAI\r ( jAk,"@Aó AP\r \r((" I\r Ak!@@@ -AÄF\r ( K\r  (O\r -" Aq\r Ak" O\r  AqE\r   \rA,jAA.AAè \rA$jOAH\r \r(,!@ \nAÀF\r@  O\r (" j-A/G\r Aj  \rA,jAA/A‰A \rA$jOAH\r \r(," O\r  j-A/G\r \r Aj"6, @  O\r ( j-A?G\r Aj  \rA,jAA&AƒA¥ \rA$jOAH\r \r(,!  O\r ( j-A#G\r Aj  \rA,jAAAAë \rA$jOAH\r \r(,! @  O\rA!A!@ ( j" ( kA4"AÿM@ A F\r A F\r A kAO\r  @@@  jAm" AtA j("Au j"AtA j(Aÿÿÿq K@ Ak!   AvAq j"AtA j(AÿÿÿqM\r Aj!  N\r  AN\r ,"@A± A P\r \r($"  (xAlj"O\r@@@ -AÄF\r ( M\r ( K\r -"Aq\r Aj" I\r  AqE\r 6 6  \n:  6  6 (t" j" 6  j" 6  -Ar:  -Ar:  \r Atr 6 A q! Aj! AàqAàG@ \r Atj Aj6 Aj! As AGqE@ \r Atj Aj6 Aj! Aq! Aq!A!A!A! A!@@ \r Atj"(("AH\r  Alj! @ ( (M\r ! ! @ (("AH\r  Alj! @ ( (M\r ! ! Aj! Aj" G\r @ E\r \r Atj((" AH\r  Alj! @ ( (M\r ! ! E\r (! (! (! !\n@@@@@@  Alj"-"A!k\n AÛk A€A˜ A*Fj -"AtAuA qj!\n@ AvAk \nAj!\n  A°A´ ( (kAFj!\n  \nAj!\n @  k"  k" K@  (" (k k j"Al"j" (6  )7  )7   k" 6  6 (t j \n(6 \n 6   O\r  Alj j" (6  )7  )7  k j"6  6 A!\n@   \nAtj"("L@@ AN@  (t Alj( "6  N\r \nAj"\nAG\r (t" Alj" 6  j" 6  -Ar:  -Ar:  AqE\r A€A˜ \nA*Fj AtAuA qj!@@@ AvAk Aj!  Aj! (6  6 -"AqE\r Aq@ (t ( Alj(!  (! Aj" H\r \rA0j$ –#Ak"$@ (E\r  3! (  (pAtj("E@A!  @  ("I\r   ( (ljO\r  (F@ ( (  AE\r A!   6  6  6  Aj6 Aj!@ ("@@   Av"Atj"D"AH@   E\r Aj!  Asj "\r A! E@A!  (! Aj$  ý#A k"$ Aß: A¦Ô;A! ( "A€ q@ A$:A! A€€€q@ Aj rA=: Aj! A€€€q@ Aj rA+: Aj! A€€q@ Aj jAü: Aj! A€€q@ Aj jAÞ: Aj! A€„q@ Aj jAþ: Aj! A! Aj jA:    AjAJ ( "AŒq@ Aq@ AÀ:A! Aq@  rA:: Aj! A€q  rA.: Aj  rA:     AjJ A€jAÿAÐü A j$ ‰ (TE@A Ak! Ak!AA ("\n j-A!F j!A!@@   jAv"Atj" ( K@ E\r  AtjAk( I\r Ak!   (M\r Aj!  @  (M" E@@  kj"@ !@  Atj("  K" KA!  "kAq"\n@@  ( j-: Aj! Aj! Aj" \nG\r  kA|M@@  ( j-:  ( j-:  ( j-:  ( j-: Aj! Aj" G\r   O\r A : Aj! Aj" Atj(! A! ($"E\rAä (, A  k   \nj!  k ! A  Aj60A! Aj !\nA!@@ \n("E\r Aj i"AH\r   kK\r \nAj!\n  j" I\r A=! AH\r A \r  e E@A!  A! (0!\n@ \n(" E\r Aj i" j" K\r Aj a \nAj!\n  K\r A \r  A€Àse \r   \rH!   AHq\r A=! +0 \r   f"AN\r \n -!\n Aj! \r E\rA!@  Atj("\n@  Atj \n cA! Aj"A\nG\r A\nO@A! \n @  Atj(\rA! Aj"A\nG\r A!   :\'A! ! !   k"  H" AÿÿÿÿsJ\rA=! \r  j"  \rH" \nK\r A   e  a A0   A€€se A0  Ae a A   A€Àse ( Ak" O\r B€”ëÜT\r Ak" > @ "I@ Ak"(E\r (¬ k"6¬ ! AJ\r AH@ AjA nAj! AæF!@A A k" A O!\n@  M@AA (!  A€”ëÜ \nv!\rA \ntAs!A! !@  (" \nv j6  q \rl! Aj" I\r AA (! E\r  6 Aj! (¬ \nj"6¬   j" " Atj   kAu J! AH\r A!@  M\r  kAuA l!A\n! ("A\nI\r@ Aj!  A\nl"O\r A AæGk AçF AGqk"  kAuA lA kH@ A„`Aìc AHj A€Èj"A m"\rAtj!\nA\n!  \rA lk"AL@@ A\nl! Aj"AG\r @ \n("  n" lk"\rE \nAj" Fq\r@ AqE@D@C! A€”ëÜG\r \nO\r \nAk-AqE\r D@C! Dà?Dð?Dø?  FDø? \r Av"F \r I!@ \r -A-G\r š! š! \n  \rk"6    a\r \n  j"6 A€”ëÜO@@ \nA6 \nAk"\nK@ Ak" A6 \n \n(Aj"6 Aÿ“ëÜK\r  kAuA l!A\n! ("A\nI\r@ Aj!  A\nl"O\r \nAj"   K! @ " M"E@ Ak"(E\r @ AçG@ Aq!\r  AsA A " J A{Jq"\n j! AA~ \n j! Aq"\r\rAw!@ \r Ak("\nE\rA\n!A! \nA\np\r@ "\rAj! \n A\nl"pE\r \rAs!  kAuA l! A_qAÆF@A!\r  jA k"A AJ"  J!  A!\r  j jA k"A AJ"  J! A!\n AýÿÿÿAþÿÿÿ \rr"J\r AGjAj!@ A_q"AÆF@  AÿÿÿÿsJ\r A AJ!    Au"s k­ d"kAL@@ Ak"A0:  kAH\r Ak" : AkA-A+ AH:  k" AÿÿÿÿsJ\r  j" AÿÿÿÿsJ\r A   j" e  a A0   A€€se@@@ AÆF@ AjA r!  K"! @ 5 d!@  G@  AjM\r@ Ak"A0:  AjK\r   G\r Ak"A0:   ka Aj" M\r @ A‰Aa  M\r AL\r@ 5 d" AjK@@ Ak"A0:  AjK\r A A Na A k! Aj" O\r A J! ! \r  @ AH\r  Aj  K!\n AjA r! !@  5 d"F@ Ak"A0: @  G@  AjM\r@ Ak"A0:  AjK\r  Aa Aj! \rrE\r A‰Aa   k"  Ha k! Aj" \nO\r AN\r A0 AjAAe   ka  ! A0 A jA Ae A   A€Àse    J!\n   AtAuA qj!@ A K\r -!Dð?!@A4 Atk"A€N@Dà! AÿI@ Aÿk!  Dð!Aý  AýOAþk!  AxJ\rD`! A¸pK@ AÉj!  D!Aðh  AðhMA’j!  Aÿj­B4†¿¢! A-F@  š ¡ š!     ¡!  (¬" Au"s k­ d"F@ Ak"A0: (¬! Ar! A q! Ak"\r Aj: AkA-A+ AH: AqE ALq! Aj!@ " ü"AÀÐj- r:  ·¡D0@¢!@ Aj" AjkAG\r Da q\r A.: Aj! Db\r A!\n Aûÿÿÿ   \rk" jkJ\r A  Aj  Ajk" Ak H  " jj" e  a A0   A€€se Aj a A0  kAAe \r a A   A€Àse    J!\n A°j$ \n ¹~  (AjAxq"Aj6 )! )!#A k"$ Bÿÿÿÿÿÿ?ƒ!~ B0ˆBÿÿƒ"§"AøkAýM@ B† B<ˆ„! A€øk­!@ Bÿÿÿÿÿÿÿÿƒ"B€€€€€€€Z@ B|!  B€€€€€€€€R\r Bƒ |! B  BÿÿÿÿÿÿÿV"! ­ |  @  „P\r BÿÿR\r B† B<ˆ„B€€€€€€€„!Bÿ  Aþ‡K@B!Bÿ  A€øAø P"\n" k" AðJ@B!B   B€€€€€€À„ \n!A!\n G@ Aj! ! !@A€ k"AÀq@  A@j­†!B!  E\r  ­"† AÀ k­ˆ„!  †! 7 7 ) )„BR!\n @ AÀq@  A@j­ˆ!B!  E\r AÀ k­†  ­"ˆ„!  ˆ!  7  7 )B† )"B<ˆ„!@ \n­ Bÿÿÿÿÿÿÿÿƒ„"B€€€€€€€Z@ B|!  B€€€€€€€€R\r Bƒ |! B€€€€€€€…  BÿÿÿÿÿÿÿV"! ­ ! A j$ B€€€€€€€€€ƒ B4†„ „¿9 ¦ (T"(! (" ( ("k"  I"@   Q  ( j"6  ( k"6    K"@   Q  ( j"6  ( k6 A: (,"6 6  ¢ E@A @  AÿM\r@AÔÚ((E@ A€qA€¿F\rAèÛA6  AÿM@ A?qA€r: AvAÀr:A  A€@qA€ÀG A€°OqE@ A?qA€r: A vAàr: AvA?qA€r:A  A€€kAÿÿ?M@ A?qA€r: AvAðr: AvA?qA€r: A vA?qA€r:A  AèÛA6 AA  :A Ñ( #Ak"\n$@@@@@@@@@@ AôM@A¤Ü("A A jAøq A I"Av"v"Aq@@ AsAq j"At"AÌÜj" (Ô\\"("F@A¤Ü A~ wq6   6 6 Aj!  Ar6  j" (Ar6 A¬Ü("M\r @@ tA t"A krqh"At"AÌÜj" (Ô\\"("F@A¤Ü A~ wq"6   6  6 Ar6 j"  k"Ar6 j 6 @ AxqAÌÜj!A¸Ü(! A Avt"qE@A¤Ü  r6   ( !  6  6  6  6 Aj!A¸Ü 6A¬Ü 6 A¨Ü(" E\r hAt(Ô^"(Axq k! !@@ ("E@ ("E\r (Axq k"   K"!  ! !  (!  ( "G@ (" 6 6 \n (" Aj ("E\r Aj !@ ! "Aj! ("\r Aj! ("\r A6 A! A¿K\r A j"Axq!A¨Ü(" E\rA! AôÿÿM@ A& Avg"kvAq AtkA>j! A k!@@@ At(Ô^"E@A!  A! A AvkA AGt!@@ (Axq k" O\r ! "\rA! !  ("   AvAqj("F ! At! "\r rE@A!A t"A kr q"E\r hAt(Ô^! E\r @ (Axq k" I!   !  ! ("  ( "\r E\r A¬Ü( kO\r (!  ( "G@ (" 6 6  (" Aj ("E\r Aj !@ ! "Aj! ("\r Aj! ("\r A6  A¬Ü("M@A¸Ü(!@ k"AO@  j" Ar6 j 6  Ar6   Ar6 j" (Ar6A!A! A¬Ü 6A¸Ü 6 Aj! A°Ü("I@A°Ü  k"6A¼ÜA¼Ü(" j"6  Ar6 Ar6 Aj! A! A/j"Aüß(@A„à(  AˆàB7A€àB€ €€€€7Aüß \nA jApqAتժs6AàA6AàßA6A€ "j"A k"q" M\rAÜß("@AÔß(" j" M\r  I\r @Aàß-AqE@@@@@A¼Ü("@Aäß!@ (" M@   (jI\r ("\r An"AF\r !A€à("Ak" q@  k  jA kqj!  O\rAÜß("@AÔß(" j" M\r I\r n" G\r   k q"n" ( (jF\r ! AF\r A0j M@ !  A„à("  kjA kq"nAF\r  j! !  AG\r AàßAàß(Ar6 n!An! AF\r AF\r M\r k" A(jM\r AÔßAÔß( j"6AØß( I@AØß 6 @A¼Ü("@Aäß!@  (" ("jF\r ("\r  A´Ü("A ME@A´Ü 6 A!Aèß 6Aäß 6AÄÜA6AÈÜAüß(6AðßA6@ At" AÌÜj"6Ô\\  6Ø\\ Aj"A G\r A°Ü A(k"Ax kAq"k"6A¼Ü  j"6  Ar6 jA(6AÀÜAŒà(6   O\r  I\r ( Aq\r  j6A¼Ü Ax kAq"j"6A°ÜA°Ü( j" k"6  Ar6  jA(6AÀÜAŒà(6  A!  A!  A´Ü( K@A´Ü 6  j!Aäß!@@  ("G@ ("\r  - AqE\r Aäß!@@ (" M@   (j"I\r (!  A°Ü A(k"Ax kAq"k"6A¼Ü  j"6  Ar6 jA(6AÀÜAŒà(6  A\' kAqjA/k" AjI"A6 Aìß)7 Aäß)7Aìß Aj6Aèß 6Aäß 6AðßA6 Aj!@ A6 Aj! Aj!  I\r  F\r  (A~q6   k"Ar6  6 AÿM@ AøqAÌÜj!A¤Ü("A Avt"qE@A¤Ü  r6  ( ! 6  6 A !A  A! AÿÿÿM@ A& Avg"kvAq AtrA>s!  6 B7 AtAÔÞj!@@A¨Ü("A t"qE@A¨Ü  r6  6  6  A AvkA AGt! (!@ "(Axq F\r Av! At!  Aqj"("\r  6  6 A! ! !A  (" 6  6  6A!A!A j 6  j 6 A°Ü(" M\rA°Ü k"6A¼ÜA¼Ü(" j"6  Ar6 Ar6 Aj!  AèÛA06A!  6 ( j6 Ax kAqj" Ar6 Ax kAqj"  j"k!@A¼Ü( F@A¼Ü 6A°ÜA°Ü( j"6  Ar6  A¸Ü( F@A¸Ü 6A¬ÜA¬Ü( j"6  Ar6  j 6  ("AqAF@ Axq! ( !@ AÿM@ (" F@A¤ÜA¤Ü(A~ Avwq6  6  6  (!@  G@ (" 6  6  @ (" Aj ("E\r Aj !@ ! "Aj! ("\r Aj! ("\r A6  A! E\r@ ("At"(Ô^ F@ AÔÞj 6 \rA¨ÜA¨Ü(A~ wq6  @  (F@  6   6 E\r  6 ("@  6  6 ("E\r  6  6  j"(!  j!  A~q6  Ar6  j 6 AÿM@ AøqAÌÜj!A¤Ü("A Avt"qE@A¤Ü  r6   ( !  6  6  6  6  A! AÿÿÿM@ A& Avg"kvAq AtrA>s!  6 B7 AtAÔÞj!@@A¨Ü("A t"qE@A¨Ü r6  6  6  A AvkA AGt! (!@ "(Axq F\r Av! At!  Aqj"("\r  6  6  6  6  (" 6  6 A6  6  6 Aj!  @ E\r@ ("At"(Ô^ F@ AÔÞj 6 \rA¨Ü A~ wq" 6  @  (F@  6   6 E\r 6 ("@ 6  6 ("E\r 6  6 @ AM@   j"Ar6 j" (Ar6   Ar6  j" Ar6  j 6 AÿM@ AøqAÌÜj!A¤Ü("A Avt"qE@A¤Ü  r6  ( ! 6  6  6  6  A! AÿÿÿM@ A& Avg"kvAq AtrA>s!  6 B7 AtAÔÞj!@@ A t"qE@A¨Ü  r6  6  6  A AvkA AGt! (!@ "(Axq F\r Av! At!  Aqj"("\r  6  6  6  6  (" 6  6 A6  6  6 Aj!  @ E\r@ ("At"(Ô^ F@ AÔÞj 6 \rA¨Ü A~ wq6  @  (F@ 6  6 E\r 6 ("@ 6  6 ("E\r 6  6 @ AM@   j"Ar6 j" (Ar6   Ar6  j" Ar6  j 6 @ AxqAÌÜj!A¸Ü(!A Avt" qE@A¤Ü  r6   ( !  6  6 6 6 A¸Ü 6A¬Ü 6 Aj! \nAj$ ‚ @ E\r Ak" Ak("Axq"j!@ Aq\r AqE\r  ("k"A´Ü(I\r j!@@@A¸Ü( G@ ( ! AÿM@  ("G\rA¤ÜA¤Ü(A~ Avwq6  (!  G@ (" 6  6  (" Aj ("E\r Aj !@ ! "Aj! ("\r Aj! ("\r A6  ("AqAG\rA¬Ü 6  A~q6  Ar6  6  6  6  A! E\r@ ("At"(Ô^ F@ AÔÞj 6 \rA¨ÜA¨Ü(A~ wq6  @  (F@  6   6 E\r  6 ("@  6  6 ("E\r  6  6  O\r ("AqE\r@@@@ AqE@A¼Ü( F@A¼Ü 6A°ÜA°Ü( j"6  Ar6 A¸Ü(G\rA¬ÜA6A¸ÜA6 A¸Ü(" F@A¸Ü 6A¬ÜA¬Ü( j"6  Ar6 j 6 Axq j! ( ! AÿM@ (" F@A¤ÜA¤Ü(A~ Avwq6   6  6  (!  G@ (" 6  6  (" Aj ("E\r Aj !@ ! "Aj! ("\r Aj! ("\r A6   A~q6  Ar6 j 6  A! E\r@ ("At"(Ô^ F@ AÔÞj 6 \rA¨ÜA¨Ü(A~ wq6  @  (F@  6   6 E\r  6 ("@  6  6 ("E\r  6  6  Ar6 j 6  G\rA¬Ü 6 AÿM@ AøqAÌÜj!A¤Ü("A Avt"qE@A¤Ü r6   ( !  6 6  6  6 A! AÿÿÿM@ A& Avg"kvAq AtrA>s!  6 B7 AtAÔÞj!@A¨Ü("A t"qE@A¨Ü  r6  6A!A  A AvkA AGt! (!@ "(Axq F\r Av! At!  Aqj"("\r  6A! !A ! !   (" 6  6A!A!A !  j 6  6 j 6AÄÜAÄÜ(Ak"A 6 ‰  E@ j A@O@AèÛA06A A A jAxq A I! Ak"("Axq!@ AqE@ A€I\r Aj M@ !  kA„à(AtM\r A   j!@  O@  k"AI\r   AqrAr6  j" Ar6  (Ar6  m  A¼Ü( F@A°Ü( j" M\r   AqrAr6  j"  k"Ar6A°Ü 6A¼Ü 6  A¸Ü( F@A¬Ü( j" I\r@  k"AO@   AqrAr6  j" Ar6  j" 6  (A~q6   Aq rAr6  j" (Ar6A!A! A¸Ü 6A¬Ü 6  ("Aq\r Axq j"\n I\r \n k! ( !@ AÿM@ (" F@A¤ÜA¤Ü(A~ Avwq6   6  6  (! @  G@ (" 6  6  @ (" Aj ("E\r Aj !@ ! "Aj! ("\r Aj! ("\r A6  A! E\r@ ("At"(Ô^ F@ AÔÞj 6 \rA¨ÜA¨Ü(A~ wq6  @  (F@ 6  6 E\r  6 ("@  6  6 ("E\r  6  6 AM@  Aq \nrAr6  \nj" (Ar6    AqrAr6  j" Ar6  \nj" (Ar6  m !  "@ Aj j"E@A  A|Ax Ak("Aq Axqj"   KQ k  «  j!@@ ("Aq\r AqE\r (" j!@@@ k"A¸Ü(G@ ( ! AÿM@  ("G\rA¤ÜA¤Ü(A~ Avwq6  (! G@ (" 6  6  (" Aj ("E\r Aj !@ ! "Aj! ("\r Aj! ("\r A6  ("AqAG\rA¬Ü 6  A~q6 Ar6  6  6  6  A! E\r@ ("At"(Ô^ F@ AÔÞj 6 \rA¨ÜA¨Ü(A~ wq6  @ (F@  6   6 E\r  6 ("@  6  6 ("E\r  6  6 @@@@ ("AqE@A¼Ü( F@A¼Ü 6A°ÜA°Ü( j"6 Ar6 A¸Ü(G\rA¬ÜA6A¸ÜA6 A¸Ü(" F@A¸Ü 6A¬ÜA¬Ü( j"6 Ar6 j 6 Axq j! ( ! AÿM@ (" F@A¤ÜA¤Ü(A~ Avwq6   6  6  (!  G@ (" 6  6  (" Aj ("E\r Aj !@ ! "Aj! ("\r Aj! ("\r A6   A~q6 Ar6 j 6  A! E\r@ ("At"(Ô^ F@ AÔÞj 6 \rA¨ÜA¨Ü(A~ wq6  @  (F@  6   6 E\r  6 ("@  6  6 ("E\r  6  6 Ar6 j 6 G\rA¬Ü 6 AÿM@ AøqAÌÜj!A¤Ü("A Avt"qE@A¤Ü  r6   ( !  6  6 6 6 A! AÿÿÿM@ A& Avg"kvAq AtrA>s! 6 B7 AtAÔÞj!@@A¨Ü("A t"qE@A¨Ü  r6  6 6  A AvkA AGt! (!@ "(Axq F\r Av! At!  Aqj"("\r  6 6 6 6 (" 6  6 A6 6 6 W~@ ­B|BøÿÿÿƒAØÚ("­|"BÿÿÿÿX@ §"?AtM\r \r AèÛA06A AØÚ 6 ß  #Ak"$  6 @ AÓM@AÐÐAÒ A jp(!  A|O@]  AÒn"AÒl"k6AÒAÐÓ Ajp"( j! AÒkAu!@A! !@@@ ! A/F@AÓ!@ n" I\r  lF\r A\nj"n" I\r  lF\r A j"n" I\r  lF\r Aj"n" I\r  lF\r Aj"n" I\r  lF\r Aj"n" I\r  lF\r Aj"n" I\r  lF\r Aj"n" I\r  lF\r A$j"n" I\r  lF\r A(j"n" I\r  lF\r A*j"n" I\r  lF\r A.j"n" I\r  lF\r A4j"n" I\r  lF\r A:j"n" I\r  lF\r AA AM!@@ j"\rA”à("E\r \n  "E@u ]  \\w ¬@  (AÿÿÿÿqAkA\n , "AH"" (  "kM@ E\r ( AH! @  j  ü\n  j!@ , AH@ 6  Aÿq:  jA:   j k  A  x …Aöÿÿÿ k O@A÷ÿÿÿ! ( , AH! AòÿÿÿM@A  j" At"  K"ArAj A I! t!@ E\r E\r  ü\n @ E\r E\r  j  ü\n   j"k!\n@  F\r \nE\r  j j  j j \nü\n A\nG@ k 6 A€€€€xr6  j \nj"6  jA: u Å@@@ , "AN@A\n! A\nF\r AjAÿq:  (" (AÿÿÿÿqAk"G\r !@ AöÿÿÿG@A÷ÿÿÿ! ( , AH! AòÿÿÿM@A Aj" At"  K"ArAj A I! t!@ E\r E\r   ü\n @  F\r  k"E\r  j  j ü\n A\nG@ k 6 A€€€€xr6  u 6 ! Aj6 (! j"A: : « A÷ÿÿÿI@ (AÿÿÿÿqAkA\n , "AH" I@A ArAj A I"t! (!@ (  "Aj"E\r E\r   AH ü\n AH@ k 6 6 A€€€€xr6  u h (Aÿÿÿÿq" K@ 6 (!@ E\r E\r   ü\n  jA: Ak  kAj ("A   x Q A\nM@ : @ E\r E\r  ü\n jA: A\n A\nk - Aÿq"A  x #A k"$#Ak"$ Aj" A j" Aj"k"A L@A= A ArgkAÑ lA v"  At(°TIkAjH\r  A¿„=M@ AÎM@ AãM@ A M@  A0r: Aj   At/àT; Aj  AçM@  AÿÿqAän"A0r:   AälkAÿÿqAt/àT; Aj   ~  AŸM@  AÎn"A0j: Aj  AÎlk~     AÿÁ×/M@ Aÿ¬âM@  AÀ„=n"A0j: Aj  AÀ„=lk   €  Aÿ“ëÜM@  A€Â×/n"A0j: Aj  A€Â×/lk€   A€Â×/n"At/àT; Aj  A€Â×/lk€ !A 6  6 A j" (6  ( 6 Aj$@ ( " Aj"k"A÷ÿÿÿI@@ A\nM@ :  Ar"Ajt! Aÿÿÿÿk6 6 6 !  k!@  F\r E\r  ü\n jA:  u A j$ 2 Aän"At/àT;  AälkAt/àT; Aj * AÎn"At/àT; Aj  AÎlk~ * AÀ„=n"At/àT; Aj  AÀ„=lk  AÐjjAÐj  t E@ ( (F F@A ("-!@ ("-"E\r G\r@ -! -"E\r Aj! Aj! F\r F Ú#AÐk"$@A ( (F\r#A@j"$  ("Ak("j!@ Ak("(AÜÖ(F@A  !   "L@ B7 A6 AØÖ6  6  6 B7 B7$ B7, A6< B€€€€€€€74  Aj  AA (( (\r B7 A6 A¨Ö6  6 AØÖ6 B7 B7$ B7, B73 A6< A:;  Aj AA (( A!@@ (( (A ($AFA ( AFA (,AF!  (AG@ (,\r ( AG\r ($AG\r (! A@k$A "E\r ("E\r AjAA8ü A:K A6  6  6 A6D  Aj A (( (,"AF@  ($6 AF ! AÐj$  A6 Aç6 AŽ 6] v ($"E@ 6 6 A6$ (86 @@ ( (8G\r ( G\r (AG\r 6 A:6 A6 Aj6$  ( ((F@   … 5 ( ((F@   … ("    (( { ("Aq! -7AF@ Au" E\r ( j(  Au E\r  ((68A!A ! ("   j A Aq (( r ( ((F@   … ( ! Aj"   ˆ@ AI\r  Atj! Aj!@   ˆ -6\r Aj" I\r š A:5@  (G\r A:4@ ("E@ A6$ 6 6 AG\r (0AF\r   F@ ("AF@ 6 ! (0AG\r AF\r  ($Aj6$ A:6 Â@ ( ƒ@  (G\r (AF\r  6 @ ( ƒ@@ ( G@  (G\r AG\r A6   6 (,AF\r Aj" ( Atj!@@@ @  M\r A;4    A Œ -6\r -5AG\r -4AF@ (AF\rA!A! -AqE\r  A! -Aq\rA  AA Aq 6, \r  A6,  Aj! ( ! Aj"     AI\r  Atj! Aj!@ ("AqE@ ($AG\r @ -6\r      Aj" I\r  AqE@@ -6\r ($AF\r      Aj" I\r  @ -6\r ($AF@ (AF\r      Aj" I\r   6  ((Aj6( ($AG\r (AG\r A:6 K ("Au! ("   Aq ( j(  j A Aq  (( I ("Au! ("  Aq ( j(  j A Aq  (( Š@ ( ƒ@  (G\r (AF\r  6 ( ƒ@@ ( G@  (G\r AG\r A6   6 @ (,AF\r A;4 ("   A  (( -5AF@ A6, -4E\r  A6,  6  ((Aj6( ($AG\r (AG\r A:6 ("     (( ¦@ ( ƒ@  (G\r (AF\r  6 ( ƒE\r@ ( G@  (G\r AG\r A6   6  6  ((Aj6(@ ($AG\r (AG\r A:6 A6, › ( ƒ@    Š -5! ( ! A:5 -4! A:4 Aj"     Œ  -4"\nr!  -5" r!@ AI\r Atj! Aj!@ -6\r@ \nAq@ (AF\r -Aq\r  AqE\r -AqE\r A;4      Œ -5" rAq! -4"\n rAq! Aj" I\r  Aq:5  Aq:4 9 ( ƒ@    Š ("      ((  ( ƒ@    Š A§ 7 AàÙ6 ("Ak" (Ak"6 AH@ A kk ” k  (  $ # kApq"$ # ‘P(A€ Þ{"type":"Document"},"attributes":{summarytbodyTableBodyLatexMathDisplay\\u%04x-+ 0X0x-0X+0X 0X-0x+0x 0xTableRowdivnavmenuTextUnorderedListOrderedListstartSuperscriptSubscripttfootcountbodyRowCountheadRowCountbasefontDocumentimportantdefaulttightrightHighlightleftframesetfieldsetdt\\taddressdetailsEmphasisnoframes%s:%d: %strvectordirhrfootercenterSpoilerheaderfenceChar\\roptgroupcolgroup/Users/ernest/react-native-enriched-markdown/packages/core/cpp/wasm/ASTSerializer.cpp/emsdk/emscripten/system/lib/libcxxabi/src/private_typeinfo.cpptipcautionoptionfigcaptionAdmonitionsectionmainalignnan\\nformmenuitemListItemparamulurlcolhtmlTableHeaderCellTableCellleveldlisTasklinkLinkCodeBlocktrackSoftBreakLineBreakThematicBreaklibad_array_new_lengthParagraphStrikethroughsearchdialogStrongbasic_stringnodeTypeToStringwarningHeadinginf\\ftrueblockquoteBlockquotenotefalsebasefigureadmonitionTypeUnderlineLatexMathInlineBlankLineiframetitlearticletableTableImageCodeasidetdlegendtaskCheckedddtheadTableHead\\b"\'=<>`-_.-+_\\\\({[,"children":[NANINFcatching a class without an object?)}].!?,;mailto:,"content":h6h5h4h3h2h1http://Too many link reference definition instantiations.Unsupported abi_version.Aborted from text() callback.Aborted from enter_span() callback.Aborted from leave_span() callback.Aborted from enter_block() callback.Aborted from leave_block() callback.malloc() failed.realloc() failed.@:..!#$%&\'*+/=?^_`{|}~-_.:-+-.-_+-_*(null)Suppressing too sparse table (see https://github.com/mity/md4c/issues/345)._=().+-_~%false && "unhandled NodeType in nodeTypeToString"\\"{"type":"[]!xX \nñ<‡í bOFß*$®ŒšŸòT2q¾Îé<Ь¸ùlAè ~€ ¸+Œ ô)NSt3__220__shared_ptr_emplaceIN8Markdown15MarkdownASTNodeENS_9allocatorIS2_EEEE"ƒA€ ¹Nú‡RA  f ° à \rˆ P\rˆ \rð\rˆ ˆ  @`€ˆ ˆ  Àˆ ˆ ˆ ˆ ˆ A ?/A° Äè£\n-Aà dƒµ¯A 5KG[uzÞ9AÐ 50a\nÉ|‘\'A MÝÚ×ÔÑÎO’y¹Að A€ 8$èA  ‚–AÀ \r~XAà ¶¦ZA€ \rP¨A  Tw$AÀ E,5Â9N\nküA ®A  —  € @\n €/ _ 0A@Z€µÀ@րØ@ހ@.€2@6€9@G€J@v€xy@}€‚„†‡‰Š‹Ž‘“”–—˜œŸ @¤€¦§©¬®¯±²³µ·¸¼ÄÅÇÈÊË@Û€Þ@î€ñòôö÷ø@€ "@2€:;=>ACDEF@N€Eprv†ˆ@Š€ŒŽ‘@¡€£@«€ÂÏÐÑÕÖØ@î€ðñôõ÷ùúý@ÿ€@€@/€`@€€Š@¾€ÀÁ@Í€Ð@.€1@V€ @Å€ÇÍø@ý€€‚ƒ„…†‡ˆ‰@º€½@¿€@”€› @þ€@€@€(@/€8@?€H@M€Y[]_h@o€¸¹º»¾È@Ë€ØÙÚÛèéêëìøùúû&!*!+!2!`!@o!€ƒ!¶$@Ï$€,@/,€`,b,c,d,g,@k,€m,n,o,p,r,u,~,,€,@â,€ë,í,ò,@¦@l¦€€¦@š¦€"§@.§€2§@n§€y§{§}§~§@†§€‹§§§’§–§@¨§€ª§«§¬§­§®§°§±§²§³§´§@§€Ä§Å§Æ§Ç§É§Ë§Ì§@Ú§€Ü§Ý§â§õ§l«m«p«@¿«€!ÿ@:ÿ€@\'€°@Ó€p@z€|@Š€Œ@’€”•€ @² €P\r@e\r€ @¿€@n@_n€ n@¸n€@ßHßJßMßQßhß@n߀rß@~߀é@!é€az¼àöøþ/37:HKwÿz~sSƒ…TˆVWŒÝY[’`cih™oru¡¥€¨ƒ­ˆ°Š‹´¶’¹½ÆÆÉÉÌÌÜßïóóõ•¿ùž#3e,<šf,B€‰ŒGO¹qswó¬­¯ÌÍαÁÃËÃײ¸ÆÀÙïºÁ¸µøòû{}P_0Oa‹¿ÏÂÎÑ/a†-%-\'---ðõ24>ABBJcK¦ŠÐúýÿ•a¡ÿ \'07@EQSUW`g°±pq¹ruÐÑvwàáz{åxy|}ÉkåN!p!!„!Ð$é$0,_,a,k}}h,l,QqPRs,v,?@,ã,ì,î,ó,A¦m¦¦›¦#§/§3§o§z§|§y§‡§Œ§e‘§“§—§©§f\\aljž‡S«µ§Ã§”§‚Žȧʧdͧۧ›w|ö§K«L« ïAÿZÿ(OØû—¡£±³¹»¼À ò p\r…\rÀß`nn»nÓnAßIßKßNßRßißoßsßß"éCéAÀ1 Óß0Ið‡–—˜™šžP€@‡€ˆ@€@—€˜@Ÿ€ @§€¨@¯€²³´¶¼ÂÃÄÆÌÖäæòóôöüûûûûûûûûûû•ßA 3 ¥ssi¼nj e‚h1tw\ny\na¾ssʹ¹¹ ¹\'¹ ¹\'¹`¹g¹`¹g¹p¹±¹¬¹±B±¹t¹·¹®¹·B·¹¹BÁÅB|¹É¹Î¹ÉBɹfffiflststtvtetk~vtmssAÐ6 À°RTV·ÇÒÓ×âãç÷ûû¹ÅÅÅÅB±B¹·B¹¹¹¹BÅÅÅBÉB¹ffiffl@.À 5P A¤9 ¬!@/€:@@€[@`€{@~€¡@©€«@¬€®@±€´¶@¸€»¿×÷Â@Å€Ò@߀å@ë€íï@ÿ€u~„@…€‡ö‚Z@_€‰@Š€@€¾ÀÃÆó@ô€@€@€j@m€ÔÞéý@þ€@\r€ö@ù€þ@ÿ€0@>€^ˆd @e €p ò @ó €ú @û €ý v\nð\n@ñ\n€p ó @ú €w  „ O\ry\rô\r?OZ@[€@€@€468:@=€…¾@Å€Ç@Ì€Î@Ú€J@O€ž@Ÿ€û`@h€@™€m@n€›@œ€ë@í€5@6€Ô@Ö€Ø@Û€@\n€@D@E€Þ@ÿ€@€ @¦€¨@­€N@O€Z@j€t@€ü@ÿ€;@?€~@€À@Ç€Ó½¿@Á€Í@Ï€Ý@߀í@ï€ý@þ€ @\' €0 @^ €z @~ €Š @Ž €  @Ä €!@!€!@!€!@ !€!!@!€!@#!€%!\'!)!.!:!@;!€@!@D!€J!@M!€O!Š!@‹!€!@)$€@$@J$€œ$@é$€%@u\'€”\'@s+€v+@ÿ+€å,@ê,€ù,@ü,€þ,@ÿ,€p-.@..€0.@].€`.@c.€€.@™.€›.@ó.€/@Õ/€ð/@ÿ/€0@0€0@ 0€0060@70€=0@?0€›0@œ0€ 0û01@‘1€–1@Ÿ1€À1@å1€ï12@2€*2@G2€P2`2@2€Š2@°2€À2@ÿ3€ÀM@ÿM€¤@Ƥ€þ¤@ÿ¤€\r¦@¦€s¦~¦ò¦@÷¦€§@§€ §@!§€‰§@Ч€(¨@+¨€6¨@9¨€t¨@w¨€Î¨@Ϩ€ø¨@ú¨€ü¨.©@/©€_©Á©@Í©€Þ©@ß©€\\ª@_ª€wª@yª€Þª@ߪ€ðª@ñª€[«j«@k«€ë«)û²û@Òû€>ý@Oý€ý@‘ý€Èý@Ïý€üý@ÿý€þ@þ€0þ@Rþ€Tþ@fþ€hþ@kþ€ÿ@ÿ€ÿ@ ÿ€;ÿ@@ÿ€[ÿ@eÿ€àÿ@æÿ€èÿ@îÿ€üÿ@ýÿ€@€7@?€y@‰€Œ@Ž€@œ€ Ð@ü€ŸÐoWw@x€ ? P\n@X\n€\nÈ\nð\n@ö\n€9 @? €™ @œ €n\rŽ\r@\r€­É@Ê€Ð@Ø€U@Y€†@‰€G@M€»@¼€¾@Á€@@C€t@u€Å@È€ÍÛÝ@߀8@=€©Ô@Õ€×@Ø€K@O€Z@[€]ÆÁ@×€A@C€`@l€¹<@?€;D@F€â?@F€š@œ€ž@¢€@ €áA@E€p@q€÷@ø€C@O€Õ@ñ€ÿp$@t$€ñ/@ò/€nj@oj€õj7k@?k€Dk@Ek€mm@om€—n@šn€âoœ¼Ÿ¼Ì@ïÌ€úÌ@üÌ€Í@³Î€ºÎ@Ð΀ÒÎ@Ô΀ÝÎ@ý΀PÏ@ÃÏ€Ð@õЀÑ@&Ñ€)Ñ@dÑ€jÑ@lÑ€ƒÑ@„Ñ€ŒÑ@©Ñ€®Ñ@AÒ€EÒSÒ@ZÒ€]Ò@^Ò€`Ò@Ò€Ó@VÓ€ÁÖÛÖûÖ×5×O×o׉ש×Ãר@ÿÙ€7Ú@:Ú€mÚ@tÚ€vÚ@ƒÚ€…Ú@‹Ú€Û@Û€Oáÿâÿå^é@_逬ì°ì.íðî@ñî€ð@+ð€0ð@“ð€ ð@®ð€±ð@¿ð€Áð@Ïð€Ñð@õð€\rñ@®ñ€æñ@ò€ò@;ò€@ò@Hò€Pò@Qò€`ò@eò€ó@Ùö€Üö@ìö€ðö@üö€÷@Û÷€à÷@ë÷€ð÷@ ø€ø@Gø€Pø@Yø€`ø@‡ø€ø@­ø€°ø@»ø€Àø@Áø€Ðø@Øø€ù@Wú€`ú@mú€pú@|ú€€ú@Æú€ÈúÌú@Ýú€ßú@ëú€ïú@úú€û@’û€”û@ïû€úû AãÌ  AðÌ A  \n\n\n   AÁÍ ! \r\r  AûÍ  A‡Î  AµÎ AÁÎ  AïÎ AûÎ  A²Ï  AãÏ AïÏ  AÐ A©Ð € 0123456789ABCDEF \r%)+/5;=CGIOSYaegkmqƒ‰‹•—£§­³µ¿ÁÅÇÓ \r%)+/5;=CGIOSYaegkmqyƒ‰‹•—£§©­³µ»¿ÁÅÇѐ+Ø)NSt3__214__shared_countE, *Ð)NSt3__219__shared_weak_countEA´Ô œ\ndè\' †@B€–˜áõʚ;00010203040506070809101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899¸+4+<-N10__cxxabiv116__shim_type_infoE¸+d+(+N10__cxxabiv117__class_type_infoEX+ !"#$%&Ø+\'!"#()*¸+ä+X+N10__cxxabiv120__si_class_type_infoE4,+!"#,-.¸+@,X+N10__cxxabiv121__vmi_class_type_infoE°,/0+„,St9exception¸+ ,|,St9bad_alloc¸+¼,”,St20bad_array_new_lengthì,12¸+ø,|,St11logic_error-32¸+(-ì,St12length_error+D-St9type_infoAÔÚ  . 0€'); -+ return binaryDecode('asm«````````````` `````||`~`|``Tenv __cxa_throwenv\r__assert_failenvemscripten_resize_heapenv _abort_js ¾¼   \r\r    \r\n     \n\n\n\np99€€@ Aã€ ¢memory__wasm_call_ctors\rparseMarkdown__indirect_function_table_emscripten_stack_restore½_emscripten_stack_alloc¾emscripten_stack_get_current¿ PA 8º \r{ !"#$%&\'()*+,~-E@G_mno{-cc¦¶³¨-µ²©-´¯¬-¸-¹-·»¼»» (\n¼è¼ AÈÜB7AÐÜA6AßÜA:AÔÜAµ(6AØÜA¹-:AÙÜA:AëÜA:AàÜAŽ/;AâÜA-:AãÜA:A÷ÜA:AìÜAç(6AðÜAë-:AñÜA:AƒÝA :AøÜA¯ )7A€ÝA· -:AÝA:AˆÝB칻֮سå7A“ÝA:AÝA:AŸÝA:A”ÝA¾(6A˜ÝAÂ/;AšÝA:A ÝA"6A¤ÝB‹€€€€‚€€€7 A£(6 Aœ)7 A: A·ÝA:A¬ÝA¼ (6A°ÝAÀ -:A±ÝA:AÃÝA:A¸ÝAÞ (6A¼ÝAâ -:A½ÝA:AÄÝA"6AÈÝBŽ€€€€‚€€€7 A³)7 A­)7 A:AìÞAôÝ6AÄÞA€€€6AÀÞAã€6A¤ÞA*6AÈÞAÀÜ(6 AÓÜ,AH@AÐÜ(AÈÜ(r ó‹!~#A0k"$@ E@AÈÜ„!AÈ܃!@ AO@AÈÜ…"A€A‰#Ak"$AÈ܃AÈÜAŠ A: Aj Aj‹ Aj$  AÈÜ A k A AA€† AÈÜAÈÜ(AÓÜ,AN  A:,  AG:/  AG:.  AG:-  AG:+  AG:*  AG:)  AG:(  AG:\'A4"A60 B7( B7 B7 B7 B7 B7 A j" 6 ! a"AøÿÿÿO\r@@ A O@ Ar"Aj!  Aÿÿÿÿk6  6  6   : A j! E\r E\r  ü\n  jA: Aj! A\'j!#AÐk"$@ A j"( , " AH"E@A<"B7 Aà6 B7 B7 B7 B7$ B74 B€€€ü7,  6  A j6  (! AéOA4 Aèn" A4OA jA !A<"\nB7 \nAà6 \nB7 \nB7 \nB7 \nB7$ \nB74 \nB€€€ü7,  \nA j6 (!  \n6@ E\r  ("\nAk6 \n\r  (( | Aj! ("! ( "\n G@@@ \nAk("E\r  ("Ak6 \r  (( |  \nAk"\nG\r (!  6 @A€  A€O"\n ( kAuM\r \nAt"!\n  k"@ \n  ü\n   \nj6  \n j6  \n6 E\r r !@@@@ ("\n ("I@ \n (6 \n ("6 @  (Aj6 \nAj!\n  \n ("k"\nAu"Aj"A€€€€O\rAÿÿÿÿ  k"Au"   K AøÿÿÿO"A€€€€O\r At"" \nj" (6  ("6  j!    (Aj6 ( ( ("k"\nAu  Atk! \n@   \nü\n  6  Aj"\n6  6 E\r r  \n6    Aj!\n@ ,AH@ (A: A6  A: A: \nA€” A:$@ ,3AH@ ((A: A6,  A:3 A:( (" (  , AH6 -! -! -! -! -! -! -!\n -! -! B7( A6$ A6 A6 A6 A6 A6  A tA̞AÀ– r \nAtr Atr Atr Atr Atr Atr Atr6 (  , "AH"! ( ! !\n#A€k" $@ A j"(@A! ("E\rA‹    A4jAAüü 6 6 )7 )7 )7 )7$ ( 6, \n60 AA ("Aq6œ A„j"AA€ü A;ã A:® A;à A:ß A: A;¿ A:ª A:¥ A:„ A€„q@ A:‚ A€€q@ A:â A€ q@ A:¨ A€€€q@ A:Á A€€€q@ A:¯ Aq@ A:Ä Aq@ A:¾ A€q@ A:² A€Âq@ A:€ Aq@A!@ A G A GqE@ jA: Ar"AýqA F@  jA: Aj"A€G\r A E\rA  jAk-"A\rF\r A\nF ! A6` A 6D 64 A€€  A€€OAt6X A„jAÿAÔü B7ä B7Ü@AA \n ("E@ AÌj!% A°jAr!& Aüj!\' AèjAr!( A°j!AÜ!A!@@ !@@ (" K@ B7ø B7ð B7èA! A°jAA  A°jF""j   F"#! (¨!) (!@@ j-"A G A Gq\r A|qAj Aj A F! Aj" G\r ! A°jA,A "j Aj #" 6 A°jA$A "j A j #" 6A! A°jA A "j Aj #"$A6@ (”"AL\r (œ! (! !\n@@  Alj"-A>F@ \n O\r O\r j-A>G\r Aj"!@ Aj" O\r@ j-"\nA G \nA Gq\r A|qAj Aj \nA F! Aj" G\r !   kAkA  G"\n6  6 !  \n ( "I\r  \n k"\n6 ! Aj" G\r ! ! 6ä@@ O\r j-A\nk  N\r (!@  Alj-A>F\r Aj" G\r ! % & " Aj #!A!\nA!A! !@A k!A k! („" (üjAk! (¬E! (! ( !\r (œ!! (¤!@@ ("AG@ !   6@ ! ("M@ !  @ " O\r  ( j-!@  j- AÿqG\r Aj" G\r ! @  k \rI\r@  O\r@@  j-A k Aj" G\r ! 6ä A6 A6¨  6ä  F@   (k"A M6 A6 !  (! @@@@ AG\r AL\r  N\rA! A6¤  O\r  j" -A\nk @ Aj  Aäj.AL\r A6¤ AþÿÿÿqAG\r A6 A6  A6 !  @ AG\r  (”G\r A6  (" (œk"A O6 A6¨  A6@@ AL"\r  G\r ( AljAk-"A>G6¨  A6¨ \r ( AljAk-! AÿqA>F\r  G\r (€@ !  („"A H@ !  (ü jAk-AG@ !  A6¬ !  @ Aq@ !    AL\r  (” G\r   Alj"Ak-A>F\r   G\r  (€\r  A H\r  -AG\r  6A AF\r   A$k(k"A M6 Ak ! A6¬ A6¨@ (" !O\r@ AG\r@ -"A-k !  G\r@@@ Aj" O\r j- F\r @@ j-A k Aj" G\r ! 6ä A6 AA A=F6 !   \nI\r -"" E\rA ÀATE\rA! Aj"\n O\r@@@  \nj-" F"\r A F\r A G\r j! \nAj"\n G\r !\n AI\r  AI\r A\nk @@@  N\r  G\r@ Aj  Aàj Aèj/E\r -è"A>F\r  Alj"-G\r (ð" ( K\r (ô" k j"!@ (à" O\r@ j-"A G A Gq\r A|qAj Aj A F! Aj" G\r 6ä   k6  6 !  6ä   k"6  6 O\r@ j-A\nk  !M@  j"6ô A6  Aj"6ô  Ak6  ! @ !O@ (AF@ !  A6  !k6 A6 !  Aj  Aäj Aèj/! (!@@ @ (ä!@ AG\r  G\r@@ O\r j-"A\rF\r -è! A\nG\r AÿqA>F\r   A>! -èA>F\r   Aÿq"A.G A)Gq\r (ìAF\r   (ô" (ðk j"!@ O\r@ j-"A G A Gq\r A|qAj Aj A F! Aj" G\r ! 6ä   k"6  6  ,è6@@@ O\r j-A\nk Aj6ô   !M@  j6ô A6  Aj6ô  Ak6 E@ Aj  j0\r (”! @ (˜" J@ (!  A Av j AL"6˜ ( Als"E@ (("E\rAå (0   6 (”! AÜ   F! Aj! Aj6”  Alj" )ø7  )ð7  )è7 (”! (! (! ! A F  Fq\r (ä!  ! O@ !  @ j"\n-"A#G@ ! AþF\r AàF\r !  Ak"\nF\rA  Aj"j-A#G\r  \nF\rA  Aj"j-A#G\r  \nF\rA  Aj"j-A#G\r  \nF\rA  Aj"j-A#G\r  \nF\rA  Aj"j-A#G\r  \nF\rA  Aj"j-A#G\r  \nF\r Aj!A  @@  j- G\r Aj" G\r !  k"AI@ !  6 @@@  M\r@  j-A G\r Aj" G\r   M\r@@  j-"A\nk @ AàG\r \n-AàG\r !  Aj" G\r ! 6ä A6 A6 $A6 \n A 6 ! " k "AJ@ !  @  M"\n\r (Aq\r  j-A k"AK@ !  A tA“€€q\r !  @ \n\r@  j-"A G A Gq\r Aj" G\r !  6 6ä A6  6  @@@@@  O\r  j-AF\r Aj" O\r A/G\r  j-A>F\r AjM@A!  A! \rAA  A jAE\rA! ( " O\r \r(!@@  j-"A k" AK\rA tA€€qE\r Aj" G\r  AAA A\nF A\rF! Aj$ "6¤@  (AG\r A6¤ ("A€qE\r (AG\r  (O\r ( j-"A-k Aj  Aäj. F@ A6¤ $A6 A6 AüG\r  (”G\r (€"E\r (AG\r Aäj!\n Aàj!A!A!\r@ Aj"(" M\r (" j-AüG\rA! Aj" O\r@  j-A k" AK\rA tA€€qE\r Aj" G\r ! @@@@  I@  ( j-A:Fj!  O\r (" j-A-G\r@@@  j-"A-G\r Aj" G\r \rAj!\r  A! \rAj!\r@  A:Fj" O\r@@  j-"A k"AK\rA tA€€qE\r  Aj"G\r  AüG\rA!A! Aj" O\r@  j-A k"AK\rA tA€€qE\r Aj" I\r !   O\r@  j-A\nk E\r  ! E\r \n 6  \r6A  A E\r  (à6 A\n6  A6 (”"   F  (AF! A€qE\r  jAL\r ( Alj"Ak-"E\r A?K\rB ­†B€€€€ÀƒP\r@ (ä" ("\n Aj"  \nK"O\r (!@ j-"A G A Gq\r Aj" G\r ! Aj" \nO\r (" j-AÛG\r  Aj"j,"E\rAà ATE\r  j-AÝG\r \n Aj"G@ j-A k"AK\rA tA“€€qE\r Ak ( " -Ar: Ak \'  6@ ("O\r (!@ j-A k"AK\rA tA€€qE\r Aj" G\r ! 6ä  6  Aj"6ô  6  6AÜ!A! ! ! Aj1A! Aj A@k2\r -Aq@ Aj AÜj2\r AjA0\r Aj3\rA!#Ak"\r$ \rA6$ Aj" A6@ (€AJ@ \rAøj!@@@@@@ (ø j"("AÿqAk \r AsA\nvAq6 \r /:  \r (6 \r (AsA\nvAq6 \r /:  \r AÿÿK6 \r /: \r (6  \rA6 \r /At(€a"6 /! \r 6 \r At(€6 \r \rAj6 \r \rA$j6 @@ ("A€q@@ A€qE\r Aÿq \rA j (, ("@ ($"E\rA¯ (,   ("Aÿq"AK\rA tAŽ€qE\r (Ak6 (! A€qE\r Aÿq \rA j (, ("@ ($"E\rAŠ (,   @ ("AÿqAk (Œ (Alj" -Ar: (Aj6  \rB7` \rB7X \rB7P \rB7H \rB7@ \rB78 \rB70 \rB7(@ ("AÿqA\nG\r A€€„I\r ("A€ Av"nM\r Aq! Aj!A!\nA!@ "AO@ A|q!A!@  Atj"( j ( j (j (j ( ( ( (jjjk! Aj! Aj" G\r E\r @  Atj"( j (k! Aj! \nAj"\n G\r  n AvO\r  ($"A¨ (,  (  A€~qA r"6 A! \rA6ˆ \rB7€ \rB7x \rB7p \rB7h ("@ (Œ AljAk-AqE! A!@@@@@@@ AÿqAk \r Av6h  A€€I\r ("\n ("j-! ( !@@@  ("O\r@  \nj- AÿqG\r Aj" G\r  M\r@  \nj-A G\r Aj" G\r ! @  M\r@  \njAk-A G\r Ak" K\r ! A!  \nj  kA \rAèj \rAÈj<\r (! !\n@  M\r@  \nj-A k"AMAA tA€€q\r \nAj"\n G\r !\n  j \n kA  \rA(j<\r \r :ˆ (!A!  \rA6l \r Av6h \r (Ak6p  \r Av6h @@@@@@@  Aÿq"A FqE@  \rAèj (, ("\r (! AÿqAk ($"E\rAŠ (,   (!@ AÿÿM@ E\r Aj!@ ( (F@ A j! Ak"\r  @  A lj"A k( Ak(G\r Ak"\r  Ak"E\r Aj! A  ="E\r  A Aj (="E\r  (!@@ Av"Atq"E@A! ($"E\rAÔ (,  r  @ (! ("! ! !@ !@ M\r (!@  j-A-F\r Aj" G\r ! A!  I@ ( jAk-A:F! @ M\r (!@@  j-"\nA-G\r Aj" G\r !  Ar  \nA:F!  At(°:6 Ak! Aj! AJ\r A A (, ("@ ($"E\rAŠ (,  r  A ( (  >"\rA A (, ("@ ($"E\rA¯ (,  r  AI\r@A A (, ("E@ Aj!A!  ($"E\rAŠ (,  r  @ A  Atj"( (  >"\r Aj" G\r A A (, ("E\r ($"E\rA¯ (,  r  r  Aj (?"\r A!  (Aÿq"A Fq\r  \rAèj (, ("E\r ($"@A¯ (,  ! \r \r(X@ \r(Hr \r(Lr \r(Pr \r(8E\r \r((r \r(,r \r(0r \r (! -AkAM@ A l j!  At j!  (Œ (Alj" -Aþq A\nvAqr: (Aj6 Aj" (€H\r A6€A! \rAj$ "\r -Aq@A!A!#A@j"$@ Aj"(`"E\r (pE\r (X AAW@@AA (, ("E@ (`E\r A0j!\n  ($"E\rAŠ (,   @ (X Alj"( E\r B7 B7 B7 B7 \nB7 \nB7  ( 6(  (6,@  ( (A \n Aj<@A!  A A(j (, ("@ ($"E\rAŠ (,    ( (?"\rA A(j (, ("E@A!  ($"E\rA¯ (,  (@ (r ( r (r \r Aj" (`I\r A!AA (, ("E\r ($"@A¯ (,  ! A@k$ \r A!AA (0 ("E\r (("@A¯ (0  !  \n6ä A6 ! @ (ä"Aj" ("O\r (!@@ j"-A\nk @ -A\nk @ -A\nk @  j-A\nk Aj! Aj!  I\r @ I@ (!@A!@ j-A\nk Aj" G\r ! A! A°jA(A "j Aj #"\n 6 " ("AG\r@@ ("M\r (!@  jAk-"A G A Gq\r Ak" K\r  @  O\r (!@  jAk-A#G\r Ak" K\r   F\r ( jAk-"A F@ !  A F@ !  ! -AqE\r \n 6  !@ AkAI\r  ("M\r (!@  jAk-"A G A Gq\r \n Ak"6  I\r @ ( j-A\rFj! I@ ( j-A\nFj! @ )E\r E\r  j"AL\r ( Alj"Ak-A>F\r (ü Ak(j" (A€r6 @ \r  j" (”N\r Aj 0\r AJ@ AjA Al" (j"(" -Aq ( j,A A4\r AjA (ü" -éAq" ( j,A A4\r ( j" -Aýq r: ( j 6 @ (”!@ -AqE\r ( Alj"Ak-A>G\r (AG\r \n(" ("k"AkA K\r (" j"-AÛG\r -A!G\r  jAk-AÝG\r Ak! Aj!A!@@@@ Ak @  j-"A k  AákAÿqAIAÿq -–"A k  AákAÿqAIAÿqG\r Aj" G\r A  @  j-"A k  AákAÿqAIAÿq -\r"A k  AákAÿqAIAÿqG@ A\nk Aj" G\r A  A!@  j-"A k  AákAÿqAIAÿq -\n"A k  AákAÿqAIAÿqG@ A\nG\r  Aj" G\r A  A!@  j-"A k  AákAÿqAIAÿq -ä"A k  AákAÿqAIAÿqG@ A\nG\r -"A k  AákAÿqAIAÿqAÃG\r -"A k  AákAÿqAIAÿqAÁG\r -"A k  AákAÿqAIAÿqAÕG\r -"A k  AákAÿqAIAÿqAÔG\r -"A k  AákAÿqAIAÿqAÉG\r -"A k  AákAÿqAIAÿqAÏG\r -"A k  AákAÿqAIAÿqAÎG\rA  Aj" G\r A ! Ak" -Ar: ( (”AljAk" -AÇq r: A6 (”!  k!@A!@@A ( Alj"-A)kt"AqE@ A!qE\rA! Aj1  („6 Aj  ( ,A4\r AjA (" -Aq ( j,A A4\r  AjAA -"AqA AvAqA4\r Aj" (”H\r @ (E@ Aj1@A!  A!AÜ! -AÀqE\r ( \n(I\r (ŒAj6Œ  (Œ@@ („"Aj" (ˆ"J@ A€ Av j AL"6ˆ (ü s"E@A! (("E\rAå (0   (€"@   (ükj6€ 6ü („"Aj6„  6„ (ü"\rA!   j"A; (Œ! A6  AtAr6 A6Œ @ $(E\r Aj1E\rA!  @@@@ ("Ak\n A! Aj1\r („"Aj" (ˆ"J@ A€ Av j AL"6ˆ (ü s"E@ (("E\r\nAå (0  \n (€"@   (ükj6€ („"Aj6„ 6ü  j  6„ (ü"E\r  j " (AtAÐÍj(" /Atr6 (! A6   Atr6 6€ Aj 5\r Aj1\rA!AÜ!  (€A: (€ /; (€" (A€r6A! Aj 5\r Aj1\rA! (€E@AÜ!  A6 !  (€A\n: (€ /; A 6AA Aj 5!  @  (F\r Aj1E\rA!  @ (€\r !@ Aj"\n(€"Aj" \n(„"J@ \nA€ Av j AL"6„ \n(ø s"E@A \n($"E\rAå \n(, A  \n(ü"@ \n   \n(økj6ü \n 6ø \n \n(€"Aj6€  j  \n 6€ \n(ø"E\r  j " (AtAÐÍj(" /Atr6 (! A6   Atr6 \n 6üA  A E\rA!  Aj 5! A! E\r  A!  (("E\rAŠ \n  (P"@ (T"A!@@ (P Atj("E\r (@" M@   (D (HljI\r r (T! Aj" I\r (P r (H@A!@ (@ Atj"-"Aq (r -  Aq@ ( r Aj" (HI\r (@r (l"@ (p"A!@@ (l Atj("E\r (\\" M@   (` (dljI\r r (p! Aj" I\r (l r (d@A!@ (\\ Alj(r Aj" (dI\r (\\r (8r (xr (ür (r A€j$ @A<"B7 Aà6 B7 B7 B7 B7$ B74 B€€€ü7,  6  A j6  (@ (("E\r ((" ($"G A$j!A!@@@  At"j("(AF@ ($" (("G\r Aj!   k"Au!@@ ((AF\rA! AG@@ Aj!  Atj"((AF@  O\r Ak(!  Atj(! \r \r !  G\r A! A68 B70A!  A! A68 B70 A6L B7D  A0j6@  AÄj6<@@@@@@  At"j"("(AG\r  Ak(A !  Aj"K@  Atj( rAG\r AF\r -A/F\r Aj" G\r ! F\r Aj  k” I@@ Aj ((  ,3AH j-bÀš Aj" G\r  (," ,3" AH"O\r Av! Aj!\n@ (  Aq!@  j"-S@ Aj" I\r  -A>F\r -A/F\r@@ K@ !@@  j"-A=F\r -S\r -A>F\r -A/F\r Aj" I\r !  G\r Aj!  A6P B7H AÈj  k”  I@@ AÈj ((  ,3AH j-bÀš Aj" I\r @@  (, ,3" AH""O\r (  !@@  j"-SE\r Aj" G\r  -A=G\r@@@@@@ "Aj"M\r  j"-S\r B78 A6@@ -A"F\r -A\'F\r !@  j" -S\r -A>F\r -A/F\r Aj" G\r !  Aj"!@ M\r -!@  j- F\r Aj" I\r ! k"  k" I"AøÿÿÿO\r@@ A O@ Ar" Aj!  Aÿÿÿÿk64  6,  60   :7 A,j! E\r E\r   j ü\n jA: ,CAH@ (@ (8r  (46@  ),78   (, ,3" AHIj!  A6@ B78 ! M\r k"  k" I"AøÿÿÿO\r@@ A O@ Ar" Aj!  Aÿÿÿÿk64  6,  60   :7 A,j! E\r E\r   j ü\n jA: ,CAH@ (@ (8r  (46@  ),78  AÈj6\\ A,j \n AÈj AÜj@ (,"Aj" A8jF\r ,C! ,AN@ AN@ (@6 )87  (8 (<™  (8 A8j AH" (<  ˜ ,CAN\r (@ (8r   A¤AƁ"AüÛ6 AˆÜA  !  AÈj6, A8j \n AÈj A,j (8",AH@ A6 (  A: Aj A: ,SAH@ (P (Hr (,! -3!   Aÿq ÀAH""I\r A!A!@ ( ," AHAG\r ( Aj AH"(Aöґ«s -Aïsr\r A:S A:K A»/;H A½-:J Aj!\nA! AÈj"( , " AH""! (  " !@ "AI\r Ak"Aq@ !  (A•ÓÇÞl"Av sA•ÓÇÞl A•ÓÇÞls! ! Aj ! AI\r !@ (A•ÓÇÞl"Av sA•ÓÇÞl (A•ÓÇÞl"Av sA•ÓÇÞl A•ÓÇÞlsA•ÓÇÞls! Aj! Ak"AK\r @@@@ Ak -At s! -At s!  -sA•ÓÇÞl! @ \n("E\r \n( A\rv sA•ÓÇÞl"Av s" Akq i"AM\r   K\r  p " Atj("E\r ("E\r Ak! AK!\n@@@  ("G@@ \nE@  q!   K\r  p!  G\r  ( ," AH" G\r ( Aj  U\r !  ("\r A  ! ,SAH@ (P (Hr E\r ( ," AHE\rA<"B7 A!6 Aà6 B7 B7 B7 A6( B74 B€€€ü7, A:S AŽ/;H A-:J A:K  AÈj6, A8j Aj AÈj A,j@ (8" F\r Aj! Aj! ,! ,AN@ AN@  (6  )7   ( (™   (  AH" (  ˜ ,SAH@ (P (Hr A j! Aj ,AH@ ( (r @ ,3AH@ ((A: A6,  A:3 A:( @ E\r ( ( "F\r Ak(!  6  6 A$j Aj@ ( "E\r ("Ak6 \r (( | A!  A! E\r  ("Ak6 \r  (( |  A! ( ( F\r  ( " (kA I\r@ Ak("E\r  ("Ak6 \r  (( |  Ak6 Aàj$ à%#A k"$@@ E@A!  @@@@@@@@@@@@@@@@ Ak\n \r  A<"B7 A6 Aà6 B7 B7 B7 A6( B74 B€€€ü7,  6Œ  A j6ˆ  )ˆ7    A<"B7 A6 Aà6 B7 B7 B7 A6( B74 B€€€ü7,@ E\r (! A:• AA  AL" ANA0r:” A”ja"AøÿÿÿO\r@@ A O@ Ar"Aj!  Aÿÿÿÿk6€  6ø  6ü   :ƒ Aøj! E\r E\r  A”j ü\n  jA: AÔÜ6˜ A¤j AjAÔÜ A˜j@ (¤"Aj" AøjF\r ,ƒ! ,AN@ AN@  (€6  )ø7   (ø (ü™   (ø Aøj AH" (ü  ˜ ,ƒAN\r (€ (ør  6ô  A j6ð (Aj6  )ð7  Aj ("Ak6 \r (( |  A<"B7 A 6 Aà6 B7 B7 B7 A6( B74 B€€€ü7,  6ì  A j6è  )è7  Aj \r A<"B7 A 6 Aà6 B7 B7 B7 A6( B74 B€€€ü7, A j!@ E\r ("E\r ("E\r AøÿÿÿO\r@ A O@ Ar"Aj!  Aÿÿÿÿk6€  6ø  6ü   :ƒ Aøj! @   ü\n  jA: (ü -ƒ" ÀAH@ AÄÝ Aøj ,ƒAN\r (€ (ør  6ä  6à (Aj6  )à7  Aj ("Ak6 \r (( | A<"B7 A\r6 Aà6 B7 B7 B7 A6( B74 B€€€ü7,  6Ü  A j6Ø  )Ø7  A j A<"B7 A6 Aà6 B7 B7 B7 A6( B74 B€€€ü7, A j!@ E\r ("AF\r Aøj œ A¬Ý Aøj ,ƒAN\r (€ (ør  6Ô  6Ð (Aj6  )Ð7(  A(j ("Ak6 \r\n (( | \n A<"B7 A6 Aà6 B7 B7 B7 A6( B74 B€€€ü7, A j!@ E\r (E\r A”Ý AøjAû" , AH@ ( (r A Ý AøjAûA› -AßqAØF" , AN\r ( (r  6Ì  6È (Aj6  )È70  A0j ("Ak6 \r (( | A<"B7 A6 Aà6 B7 B7 B7 A6( B74 B€€€ü7, A j!@ E\r@ - "E\r A:¥  :¤ AøÜ Aøj A¤j" , AN\r ( (r ("E\r ("E\r AøÿÿÿO\r\n@ A O@ Ar"Aj!  Aÿÿÿÿk6€  6ø  6ü   :ƒ Aøj! @   ü\n  jA: (ü -ƒ" ÀAH@ AˆÝ Aøj ,ƒAN\r (€ (ør  6Ä  6À (Aj6  )À78  A8j ("Ak6 \r (( |  A<"B7 A6 Aà6 B7 B7 B7 A6( B74 B€€€ü7,  6¼  A j6¸  )¸7@  A@k  A<"B7 A6 Aà6 B7 B7 B7 A6( B74 B€€€ü7, A j!@ E\r Aøj (œ A¸Ý6˜ A¤j AjA¸Ý A˜j@ (¤"Aj" AøjF\r ,ƒ! ,AN@ AN@  (€6  )ø7   (ø (ü™   (ø Aøj AH" (ü  ˜ ,ƒAN\r (€ (ør  6´  6° (Aj6  )°7H  AÈj ("Ak6 \r (( |  A<"B7 A6 Aà6 B7 B7 B7 A6( B74 B€€€ü7, A j!@ E\r A:€ BãÞ±›ô­·ô7ø A:ƒ A¤j (œ  Aøj6” A˜j Aj" Aøj A”j@ (˜"Aj" A¤jF\r ,¯! ,AN@ AN@  (¬6  )¤7   (¤ (¨™   (¤ A¤j AH" (¨  ˜ ,¯AH@ (¬ (¤r ,ƒAH@ (€ (ør A"6ø BŒ€€€€‚€€€7ü Aù (6 Añ )7 A: A¤j (œ  Aøj6” A˜j  Aøj A”j@ (˜"Aj" A¤jF\r ,¯! ,AN@ AN@  (¬6  )¤7   (¤ (¨™   (¤ A¤j AH" (¨  ˜ ,¯AH@ (¬ (¤r ,ƒAH@ (€ (ør A"6ø BŒ€€€€‚€€€7ü Aì (6 Aä )7 A: A¤j (œ  Aøj6” A˜j  Aøj A”j@ (˜"Aj" A¤jF\r ,¯! ,AN@ AN@  (¬6  )¤7   (¤ (¨™   (¤ A¤j AH" (¨  ˜ ,¯AH@ (¬ (¤r ,ƒAN\r (€ (ør  6   6œ (Aj6  )œ7P  AÐj ("Ak6 \r (( |  A<"B7 A6 Aà6 B7 B7 B7 A6( B74 B€€€ü7,  6˜  A j6”  )”7X  AØj  A<"B7 A6 Aà6 B7 B7 B7 A6( B74 B€€€ü7,  6  A j6Œ  )Œ7`  Aàj  A<"B7 A6 Aà6 B7 B7 B7 A6( B74 B€€€ü7,  6ˆ  A j6„  )„7h  Aèj  A<"B7 Aà6 B7 B7 B7 A6( B74 B€€€ü7, AA AF6 @ E\rAš\n! (Ak"AM@ At(Ð! A:ƒ A:ý Aá\r(6ø Aå\r-:ü a"AøÿÿÿO\r@@ A O@ Ar"Aj!  Aÿÿÿÿk6¬  6¤  6¨   :¯ A¤j! E\r E\r   ü\n jA:  Aøj6” A˜j Aj Aøj A”j@ (˜"Aj" A¤jF\r ,¯! ,AN@ AN@ (¬6 )¤7  (¤ (¨™  (¤ A¤j AH" (¨  ˜ ,¯AH@ (¬ (¤r ,ƒAN\r (€ (ør  6€  A j6|  (Aj6  )|7p  Aðj  ("Ak6 \r  (( |  A:$ ,3AH@ ((A: A6,  A:3 A:( A j$    #Ak"$@ ( ," AHE\r ( " (F\rA<"B74 B€€€ü7, A6 Aà6 B7 B7 B7$  Aj")7  (6 A: A: Ak(!  6  A j6 A$j Aj@ ( "E\r  ("Ak6 \r  (( | ,AH@ (A: A6  A: A: Aj$ ª~A!@@@ (Ak ( ," AH""E\r  ( Aj "j! !@@ 1"B?V\rB †B€Ì€€ƒP\r Aj" G\r  kAF A!  ¹  #Ak"$ ("(" ("kAu!@  F\r@  Atj(E\r Aj" G\r ! @@ " M\r  Ak"Atj(\r A<"B7 A6 Aà6 B7 B7 B7 A6( B74 B€€€ü7,  6  A j6 A0j!  At"j!  At"j!@  kAu" (" ("kAuM@ (" k"Au I@  j!  G@@ (! ("@  (Aj6  6 (!  6@ E\r  ("Ak6 \r  (( | Aj! Aj" G\r (! !  G@@  (6  ("6 @  (Aj6 Aj! Aj" G\r    kj6   G@@ (! ("@  (Aj6  6 (!  6@ E\r  ("Ak6 \r  (( | Aj! Aj" G\r (!  G@@@ Ak("E\r  ("Ak6 \r  (( |  Ak"G\r  6  @ ! (" G@@@ Ak("E\r  ("Ak6 \r  (( |  Ak"G\r ( (!  6 r A6 B7A! @ A€€€€O\rAÿÿÿÿ Au"  K AøÿÿÿO"A€€€€O\r  At""6  6   j6  G@@  (6  ("6 @  (Aj6 Aj! Aj" G\r  6   ( Aj@ ( "E\r  ("Ak6 \r  (( | ("(! (!  G@@@ Ak("E\r  ("Ak6 \r  (( |  Ak"G\r  6 Aj$ A„  )A¤€"A€Ú6 A”Ú6 AèÚA  ~ AL@ (" ("kAu N@  k"Au"\n H@@   j" F@ !  ! !@  (6  ("6 @  (Aj6 Aj! Aj" G\r 6 \nAL@  At"j! !   k"K@ !@  (6  (6 B7 Aj! Aj" I\r 6  G@@ Ak")! B7 Ak(! Ak" 7@ E\r  ("Ak6 \r  (( |  G\r  F@ !@ (! ("@  (Aj6  6 (!  6@ E\r  ("Ak6 \r  (( | Aj! Aj" G\r   At"j! !   k"K@ !@  (6  (6 B7 Aj! Aj" I\r 6  G@@ Ak")! B7 Ak(! Ak" 7@ E\r  ("Ak6 \r  (( |  G\r  Atj! !@ (! ("@  (Aj6  6 (!  6@ E\r  ("Ak6 \r  (( | Aj! Aj" G\r  @  ("kAu j"A€€€€I@Aÿÿÿÿ  k"Au"   I AøÿÿÿO" A€€€€O\r AtA "  kj! At"Ak"Aq   (6  ("6 @  (Aj6 Aj! Aj !  j! @@  (6  ("6 @  (Aj6  (6  ( "6 @  (Aj6 Aj! Aj" G\r ( k"@   ü\n 6   ("k"k! @   ü\n  j6 6 ( Atj6 @ r    Ý#A k"$ ($" (("G@@ ( Aj" G\r @ (AG\r ($" (("F\r !@@@@@ (("  k"AH\r  "6  6   j6 A6 B7  Aj6  Aj6@ Aj!@@ (("  Aj!    Aj"G\r  Aj" G\r    ($"@ " (("G@@@ Ak("E\r  ("Ak6 \r  (( |  Ak"G\r ($! 6( (, r (6$ (6( (6, A6 B7 ("E\r " ( "G@@@ Ak("E\r  ("Ak6 \r  (( |  Ak"G\r (!  6 ( r ("E\r " ("G@@@ Ak("E\r  ("Ak6 \r  (( |  Ak"G\r (!  6 ( r A j$ ¶ ~#A k"$@@@ ($" (("F\r@ ("("A G A GqE@  Aj" G\r ((" ($"F\r A$j! @  \nAt"\rj("(" A\rkAO \nAjA!@ ($" (("F\r !@@@ ("(AG\r (( ($"kAG\r ((A!F\r Aj" G\r  A6 B7 A6 B7@@@ ("(AG\r (( ($"kAG\r ((A!G\r (" ( "G@A<"B7  6 Aà6 B7 B7 B7 B€€€€€€€À?7(  6  A j6  (68  64  60 A6 B7 Aj @ ("E\r  ("Ak6 \r  (( | (($! (" ("I@  (6  ("6 @  (Aj6  Aj6   ("k"Au"Aj"A€€€€O\rAÿÿÿÿ  k"Au"   I AøÿÿÿO"A€€€€O\r At"" j" (6  ("6  j!    (Aj6 ( ( k"Au  Atk! @   ü\n  6  Aj"6  6 @ r  6  Aj  Aj" G\r @ (" ( "F\rA<"B7  6 Aà6 B7 B7 B7 B€€€€€€€À?7(  6  A j6  (68  64  60 A6 B7 Aj  ("E\r  ("Ak6 \r  (( | ($ \rj" ! Aj" (("G@@ )! B7 (!  7@ E\r  ("Ak6 \r  (( | Aj! Aj" G\r ((!  G@@@ Ak("E\r  ("Ak6 \r  (( |  Ak"G\r 6( (" ("  kAu (" ! ( k! ("@ " ( "G@@@ Ak("E\r  ("Ak6 \r  (( |  Ak"G\r (!  6 ( r (! @ " ("G@@@ Ak("E\r  ("Ak6 \r  (( |  Ak"G\r (!  6 ( r Au! ($! ((!  \nj !\n \n  kAuI\r A j$   Þ#Ak"$ @ ("E\r ( " (F\r Ak(! ("@  (Aj6 Aj!  6  6 A$j Aj@ ( "E\r ("Ak6 \r (( |   @ ("E\r  ("Ak6 \r  (( | Aj$ ¢  } ( , " AH""! (  " !@ "AI\r Ak"Aq@ !  (A•ÓÇÞl"Av sA•ÓÇÞl A•ÓÇÞls! ! Aj ! AI\r !@ (A•ÓÇÞl"Av sA•ÓÇÞl (A•ÓÇÞl"Av sA•ÓÇÞl A•ÓÇÞlsA•ÓÇÞls! Aj! Ak"AK\r @@@@ Ak -At s! -At s!  -sA•ÓÇÞl! A\rv sA•ÓÇÞl"Av s! @ ("E\r (  Akq i"AM\r   K\r  p "Atj("E\r ("E\r Ak!\n AK! @@  ("G@@ E@  \nq!   K\r  p!  F\r  ( ," AH G\rA ( Aj AH UE\r ("\r A " 6 A6 Aj!@ (", AN@  (6  )7  (! (!\n#Ak" $@@@ \n‘@ " \n’  \nA÷ÿÿÿK\r Aj \nŒAj“ (   ("6  (   \n6   \nAj‰ Aj$   A6 B7 *!\r ( Aj³!@ @ \r ³” ]E\r @A  AkqAG AIr Atr"  \r•ü"  K"AF\r   AkqE\r w " ("M@  M\r ( ³ *•ü! @ AI\r iAK\r AA Akgkt AI  w "  K" O\r !@@ "@ A€€€€O\r At"! (!  6 @ ( r (!  6 @ A ü ("E\r Aj! (!@ i" AM@  Akq!   I\r  p! Atj 6 ("E\r Ak!\n AK! @ (!@ E@  \nq!   I\r  p! @  F@ !  Atj" (E@ 6 ! !   (6  ((6 ( 6 ("\r  (! A6 @ ( r A6   (" Ak"qE@  q!   K@ !   p! @ (" Atj"("E@  (6  6  Aj6 ("E\r (!@  Ak"qE@  q!   K\r  p!  Atj 6   (6  6  ( Aj6 A : 6 ¡#Ak"$  6 Aj Aj  Aj@ ("Aj" F\r , ! ,AN@ AN@  (6  )7   ( (™   (  AH" (  ˜ Aj$ } a"AøÿÿÿI@@@ A O@ Ar"Aj! Aÿÿÿÿk6 6 6  : ! E\r E\r   ü\n  jA:   o ("@@ (! ,AH@ ( (r ,AH@ ( (r r "\r (! A6 @ ( r  (" ("I@  (6  (6 B7 Aj6 @  ("k"Au"Aj"A€€€€I@Aÿÿÿÿ  k"Au"   I AøÿÿÿO" A€€€€O\r AtA " j" (6  (6 B7  Atk! @   ü\n  Atj6 Aj"6 6 @ r 6   Î#Ak"$ @ ("E\r ( ( "F\r Ak(! ("@ (Aj6  6  6 A$j Aj ( "E\r ("Ak6 \r (( | @ ("E\r  ("Ak6 \r  (( | Aj$ Ý#A0k"$ ("(" ("G@ !@@@ (@  Aj"G\r  A<"B7 A6 Aà6 B7 B7 B7 A6( B74 B€€€ü7,  6  A j6 A: A¢\n(6 A¦\n-: A: A: AôäÕ«6 A:  A j6$ A(j Aj A j A$j@ (("Aj" F\r ,AN@  (6  )7   A˜ , AN\r ( (r ,AH@ ( ( r (! (0"@ " (4"G@@@ Ak("E\r  ("Ak6 \r  (( |  Ak"G\r (0!  64 (8 r A68 B70  (60  (64  (68 A6 B7 ( Aj ("E\r  ("Ak6 \r  (( |  @ (  Aj" G\r ("(" ("G@@@ Ak("E\r  ("Ak6 \r  (( | Ak"G\r  6 A0j$ AßÜ,AH@AÜÜ(AÔÜ(r AëÜ,AH@AèÜ(AàÜ(r A÷Ü,AH@AôÜ(AìÜ(r AƒÝ,AH@A€Ý(AøÜ(r A“Ý,AH@AÝ(AˆÝ(r AŸÝ,AH@AœÝ(A”Ý(r A«Ý,AH@A¨Ý(A Ý(r A·Ý,AH@A´Ý(A¬Ý(r AÃÝ,AH@AÀÝ(A¸Ý(r AÏÝ,AH@AÌÝ(AÄÝ(r Aà6  Aà6 r ¬#Ak"$ A j"($"@ " (("G@@@ Ak("E\r ("Ak6 \r (( |  Ak"G\r ($!  6( (, r Aj ,AH@ (  (r Aj$  r µ  (!@@@@@@@@@@@@ ( Ak  Aj"M@  6A Ak! (!@@ ! !@ j"-"AF\r @ Aj" O\r -"A k  AákAÿqAIAÿqAÓG\r -"A k  AákAÿqAIAÿqAÃG\r -"A k  AákAÿqAIAÿqAÒG\r -"A k  AákAÿqAIAÿqAÉG\r -"A k  AákAÿqAIAÿqAÐG\r -"A k  AákAÿqAIAÿqAÔG\r  j-A>F\r @ Aj" O\r -"A k  AákAÿqAIAÿqAÓG\r -"A k  AákAÿqAIAÿqAÔG\r -"A k  AákAÿqAIAÿqAÙG\r -"A k  AákAÿqAIAÿqAÌG\r -"A k  AákAÿqAIAÿqAÅG\r  j-A>F\r A\nj" O\r -"A k AákAÿqAIAÿqAÔG\r -"A k AákAÿqAIAÿqAÅG\r -"A k AákAÿqAIAÿqAØG\r -"A k AákAÿqAIAÿqAÔG\r -"A k AákAÿqAIAÿqAÁG\r -"A k AákAÿqAIAÿqAÒG\r -"A k AákAÿqAIAÿqAÅG\r - "A k AákAÿqAIAÿqAÁG\r  j-A>F\r\r Aj" G\r !  6A Aj" O\r Ak! (!@@  j"-A\nk\n\n /A­Ús -A>srE\r Aj! Aj!  I\r !  Aj" O\r Ak! (!@@  j"-A\nk /A¿üF\r Aj! Aj!  I\r !  Aj" O\r Ak! (!@@@  j-"A\nk  A>F\r Aj! Aj!  I\r !  Aj" O\r Ak! (!@@  j"-A\nk /Aݺs -A>srE\r Aj! Aj!  I\r !  @@  O\rA! ( j-A\nk  6 ( !   6A  6A  6A  6A  6A  Aj6A Å@  ("O\r  (˜O\r @ (" j-"E\r A>F@ A>:  6  -Aüq: Aj! Aj  A?K\rB ­†B€€€€€ ƒP\r  Aj"K@  j-A k"AK\rA tA“€€qE\r  :  6  -Aüq: Aj  A! A6  A j"  I"\nO\rA! !@@ j-" A0kAÿqA K\r  A\nljA0k"6 Aj" \nG\r \n! M\r O\r@ j-" A)k  Aj"K@  j-A k"AK\rA tA“€€qE\r  :  6  -Aüq:  k jAj 6  6A!  ç  ("H@@A!@@@A (Œ Alj"Ak"-A)kt"AqE@ A!qE\rA! Ak(!A! Ak-Aq@ ( j,! A! A  A4\r A ,A4\r  AA Ak-"AqA AvAqA4E\rA!  (Ak"6  H\r A Þ#A0k"$@ (ü"E\r@@@ ("AÿqAk A€qE\r (" (O\r ( j-AÛG\r@ ("E\r Aj! AG\r !  @ \r@ A/G\r Aj" O\r \n j-A>F\r AL\r@ AßqAÁkAÿqAI\r AßF\r A:G\r  Aj"M@A!  @@@ \nj,"A0kAÿqA\nI\r A_qAÁkAÿqAI\r E@A!  A ATE\r A!  Aj"G\r  A!  A! @@ Ak A=G\r Aj!A!  A+!@@@@ A"k E\r AÑ AT\r A\rF\r A)!  A*! Aj! I\r A! E\r \rF\rA  A)FA !  Aj" Atj"(! (" I\r   M@A A!  Aj6 „#Ak"$@  O\r@@@ j"  k A j7"AÿK@A!A!@@@  jAm"AtA°j("\nAu j"AtA°j(Aÿÿÿq K@ Ak!   \nAvAq j"AtA°j(AÿÿÿqM\r Aj!  L\r  AH\r  A F\r A F\r A kAI\r -A\nk ( j" I\r Aj$  à@@@ AÿK@A­!@@@  jAm"AtAÐj("Au j"AtAÐj("Aÿÿÿq K@ Ak!  AvAq j"AtAÐj(AÿÿÿqM\r Aj!  N\r  AH\rAà9!  A6  A r AÁkAI6 A!A4!@@@  jAm"AtAÐ2j("Au j"AtAÐ2j("Aÿÿÿq M@ AvAq j"AtAÐ2j(Aÿÿÿq O@ AH\rAð9!  Aj!  Ak!  N\r A!A!@@@  jAm"AtAà7j("Au j"AtAà7j("Aÿÿÿq M@ AvAq j"AtAà7j(Aÿÿÿq O@ AH\rA€:!  Aj!  Ak!  N\r A6  6  ( ( " lAtj! At"@   ü\n  6 F\r ( Aÿÿÿq"AjF@  sAsAq j6  ( kj6 õ #A k"$ B7 B7 B7 B7 A B! A B! @@@  K@   M\r @ \nE@   AjF!A! AqE@   F! A!  Atj( Aj Atj(k"\r Aj" ( " I! Aj" (" I!\n  K\r  I\r  K\r  I\r A! A j$  iA!@ ("(" ("("I\rA!  K\r ( ( ( (D"\rA! (" ("I\r K!  ‰#Ak"$@@@  O\r j  k A j7! ( j! AÿK@A!@@@  jAm"AtA°j("\nAu j" AtA°j(Aÿÿÿq K@ Ak!   \nAvAq j"AtA°j(AÿÿÿqM\r Aj!  L\r  AN\r  A F\r A F\r A kAO\r A6 A 6  B!   C Aj$  D ("(" ("("I@A  K@A ( ( ( (D ž“#A0k"$ A6x#Ak"$ AjAA€ü @@@ E\r Ak! A€j!\r  AtjAk!@  Atj"(!@ !@ !@ Aj" ("O@ !  (! @ \r  j"-j-@ !  \r -j-@ !  \r -j-@ !  \r  j-j-@ !  Aj! Aj"!  K\r @  K@ (!@ \r  j"-" j-\r Aj" G\r Aj" I\r  @AA@@@@@@ AÜF@A! Aj" (O\r@  j-"A!kAÿqAI\r@ AÿqA\nku Aj I\r Aj! @@ (x" (|"N@ AÀ Av j AL"6| (t Als"\rA! ($"\rE\rAå (, \r  Aj6x (t"\r  6t (x"Aj6x  Alj"AÜ ; B7  Aj"6  6 A!@@@@@@@@@@@@ A!k\\ \r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\n\r \r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r Aj"!\n@  M\r@  \nj- G\r \nAj"\n I\r !\n A!A!A!  (F\r Q"AÿM\rA! A!@@@@  jAm" AtA°j("Au j"AtA°j(Aÿÿÿq K@ Ak!   AvAq j" AtA°j(AÿÿÿqM\r Aj!  N\r  A! AN\r A! Aä!@@@  jAm" AtAÀ:j("Au j"AtAÀ:j(Aÿÿÿq K@ Ak!   AvAq j" AtAÀ:j(AÿÿÿqM\r Aj!  N\r A! AN   k! !@@  j-" AàG\r Aj" G\r !A  A F ! !  k"A K\r At j( "  AtjAk(O\rA!A!@ E@ ! !\n  !\n  " I\r @@@@ \nO\r@  j-"A G@ AàF\rA! Aj" \nG\r A! \n  ! \nO@A! !  @  j-AàG" @ ! !  Aj" \nG\r ! \n! @  k"F@A!\n  Atj" (" I@  jAk-A F!\n As  Gq\r \r F \nrE\r E\r Aj  @ F\rA! AK\r At jA j" (" K6 \r  Aj"M@A!   Atj"\n(! \n(!\n  ( ! \n@ Ak!  Ak(" ("O\r@  j-"A G A Gq\r Aj" G\r ! @@ (x" (|"N@ AÀ Av j AL"6| (t Als"\rA! ($"\rE\rAå (, \r  Aj6x (t"\r  6t (x"Aj6x  Alj"Aà; B7  6  6@@ (x" (|"N@ AÀ Av j AL"6| (t Als"\rA! ($"\rE\rAå (, \r  Aj6x (t"\r  6t (x"Aj6x  Alj"Aà; B7  6  6 (t (x"Alj"Ak" Ak6 A(k" Ak6  -Ar:  -Ar:A! ! ! ! (M\r@@@@   jAv"Atj"( K@ E\r  AtjAk( I\r Ak!  (K\r ! ! !  Aj! A!  M\r ! !  @@ (x" (|"N@ AÀ Av j AL"6| (t Als"\rA! ($"\rE\rAå (, \r  Aj6x (t"\r  6t (x"Aj6x  Alj"A¦; B7  Aj"6  6  (x"AL\r (t" AljAk-A&G\r (|" L@ AÀ Av j AL"6|  Als"E@A! ($"\rE\rAå (, \r  6t (x! Aj6x  Alj"A»; B7  Aj6  6  ("\n - AÀq\r\n   k"  \n A jA\r (" AjM\r -A!G\r  Aj"j-A-G\r -A-G\r A! (è" K  \nAkOq\r @ Aj" \n \nI"M@  j" /A­Ús -A>srE\r\r@@ Aj! Aj" K\r " j" /A­Ús -A>sr\r  !  \nI Aj" Kq@  Atj"(! (!  6è (! A! -AqE\r Aj" O\r  j-AüG\r@@ (x" (|"N@ AÀ Av j AL"6| (t Als"\rA! ($"\rE\rAå (, \r  Aj6x (t"E\r  6t (x"Aj6x  Alj"Aü; B7  Aj"6  6  ("Aj K\r  Ak"j"/A÷îs -A÷sr\r @  F\r Q"AÿK@A!A!@@@@  jAm" AtA°j("\nAu j"AtA°j(Aÿÿÿq K@ Ak!   \nAvAq j"AtA°j(AÿÿÿqM\r Aj!  N\r  AN\r A!Aä!@@@  jAm" AtAÀ:j("\nAu j"AtAÀ:j(Aÿÿÿq K@ Ak!   \nAvAq j"AtAÀ:j(AÿÿÿqM\r Aj!  N\r  AH\r\r  A F\r A F\r A\rkA}K\r A!kAI\r A:kAI\r AÛkAI\r AÿG AúKqE\r @@ (x" (|"N@ AÀ Av j AL"6| (t Als"\rA! ($"\rE\rAå (, \r  Aj6x (t"E\r  6t (x"Aj6x  Alj"A®; B7  Aj"6  6@@ (x" (|"N@ AÀ Av j AL"6| (t Als"\rA! ($"\rE\rAå (, \r  Aj6x (t"E\r  6t (x"Aj6x  Alj" (6 (! AÄ; B7  6  Aj!@@ (" Aj K\r  Ak"\nj(AèèуG\r  M\r /A¯ÞF\r @ Aj K\r  Ak"\nj"(Aèèуs -Aósr\r  M\r /A¯ÞF\r Aj K\r  Ak"\nj"/Aæès -Aðsr\r  M\r /A¯ÞG\r @@ (x" (|"N@ AÀ Av j AL"6| (t Als"\rA! ($"\rE\rAå (, \r  Aj6x (t"E\r  6t (x"Aj6x  Alj"Aº; B7  6  \n6@@ (x" (|"N@ AÀ Av j AL"6| (t Als"\rA! ($"\rE\rAå (, \r  Aj6x (t"E\r  6t (x"Aj6x  Alj" (6 (! AÄ; B7  6 Aj!  (Aj K\r @ Ak-"AßqAÁkAÿqAO@ Aj O\r A0kAÿqA\nO\r  Aj O\r\n  Aj"j-"A0kAÿqA\nO@ A_qAÁkAÿqAK\r\n @@ (x" (|"N@ AÀ Av j AL"6| (t Als"\rA! ($"\rE\rAå (, \r  Aj6x (t"E\r  6t (x"Aj6x  Alj"AÀ; B7  6  6@@ (x" (|"N@ AÀ Av j AL"6| (t Als"\rA! ($"\rE\rAå (, \r  Aj6x (t"E\r  6t (x"Aj6x  Alj" (6 (! AÄ; B7  6 Aj!  @@ (x" (|"N@ AÀ Av j AL"6| (t Als"\rA! ($"\rE\rAå (, \r  Aj6x (t"E\r  6t (x"Aj6x  Alj"AÝ; B7  Aj"6  6 \r @@ (x" (|"N@ AÀ Av j AL"6| (t Als"\rA! ($"\rE\rAå (, \r  Aj6x (t"E\r  6t (x"Aj6x  Alj" 6A!A  Aj" O\r  j-AÛG\r@@ (x" (|"N@ AÀ Av j AL"6| (t Als"\rA! ($"\rE\rAå (, \r  Aj6x (t"E\r  6t (x"Aj6x  Alj" 6A!!A !  :  : B7   j"6@@ (x" (|"N@ AÀ Av j AL"6| (t Als"\rA! ($"\rE\rAå (, \r  Aj6x (t"E\r  6t (x"Aj6x  Alj"AÄ; B7  6  6@@ (x" (|"N@ AÀ Av j AL"6| (t Als"\rA! ($"\rE\rAå (, \r  Aj6x (t"E\r  6t (x"Aj6x  Alj"AÄ; B7  6  6 \n @@ E@  -\rA qAvq\r  E\r @@ (x" (|"N@ AÀ Av j AL"6| (t Als"\rA! ($"\rE\rAå (, \r  Aj6x (t"E\r  6t (x"Aj6x  Alj"A:  : B7  Aj"6  6 \n !@@@@@@@@@AA@@AA@@@@@@@@@@ > AþF\r AÞG\r -AqE\r Aj" !@  M\r@@  j-AÞG\r Aj" I\r ! !  kAG\r A! A!  j ( kA7"AÿM@ A F\r A F\r A kAM\rA  @@@  jAm"AtA°j("Au j"\nAtA°j(Aÿÿÿq K@ \nAk!   AvAq j"AtA°j(AÿÿÿqM\r Aj!  N\r A  \nAN\rA  A !  (F\r Q"AÿM\rA!A!@@@  jAm" AtA°j("Au j"\nAtA°j(Aÿÿÿq K@ \nAk!   AvAq j"AtA°j(AÿÿÿqM\r Aj!  N\r !  \nAN\r !  -A qE\r@ Aj" O\r  j" -A=F\r !  kAG\rA!A!AA ( kA7"AÿM@A! A F\r A F\r A kAI  @@@  jAm" AtA°j("Au j"\nAtA°j(Aÿÿÿq K@ \nAk!   AvAq j"AtA°j(AÿÿÿqM\r Aj!  N\r A!\n \nAN !  -A€qE\r@ Aj" O\r  j" -A+F\r !  kAG\rA!A!AA ( kA7"AÿM@A! A F\r A F\r A kAI  @@@  jAm" AtA°j("Au j"\nAtA°j(Aÿÿÿq K@ \nAk!   AvAq j"AtA°j(AÿÿÿqM\r Aj!  N\r A!\n \nAN !  A! Aj"\n!@  \nM"\r@  j-AþG" \r Aj" I\r ! @  k"AF@ ( "A€€qE\r@ \rA! A!  \nj ( \nkA7"AÿM@ A F\r A F\r A kAM\rA  @@@  jAm"AtA°j(" Au j"AtA°j(Aÿÿÿq K@ Ak!   AvAq j"AtA°j(AÿÿÿqM\r Aj!  N\r A  AN\rA  A !  (F\r Q"AÿM\r\rA!A!@@@  jAm" AtA°j(" Au j"AtA°j(Aÿÿÿq K@ Ak!   AvAq j"AtA°j(AÿÿÿqM\r Aj!  N\r !  AN\r !  ! AK\r ( ! ! A€qE\rA!  (M\r\n Q"AÿM\rA!\nA!@@@@  \njAm"AtA°j(" Au j" AtA°j(Aÿÿÿq K@ Ak!   AvAq j"\nAtA°j(AÿÿÿqM\r \nAj!\n  \nN\r  AN\r A!\nAä!@@@  \njAm"AtAÀ:j(" Au j" AtAÀ:j(Aÿÿÿq K@ Ak!   AvAq j"\nAtAÀ:j(AÿÿÿqM\r \nAj!\n  \nN\r A! AN @ Aj" O" E@  j-A$F\r !  kAK\rA!  (M\r Q"AÿM\rA!\nA!@@@@  \njAm"AtA°j(" Au j" AtA°j(Aÿÿÿq K@ Ak!   AvAq j"\nAtA°j(AÿÿÿqM\r \nAj!\n  \nN\r  AN\r A!\nAä!@@@  \njAm"AtAÀ:j(" Au j" AtAÀ:j(Aÿÿÿq K@ Ak!   AvAq j"\nAtAÀ:j(AÿÿÿqM\r \nAj!\n  \nN\r A! AN  @ Aj" O\r@  j-A k"AK\rA tA€€qE\r Aj" I\r ! A F@ !  kAI\r @@ (x" (|"N@ AÀ Av j AL"6| (t Als"\rA! ($"\rE\r!Aå (, \r ! Aj6x (t"E\r  6t (x"Aj6x  Alj"A:  : B7  6  6  @@ (x" (|"N@ AÀ Av j AL"6| (t Als"\rA! ($"\rE\r Aå (, \r Aj6x (t"E\r  6t (x"Aj6x  Alj"A€ ; B7  Aj"6  6  A! !  kAG\r A! !  kAG\r A F\r A F\r A\rkA}K\r AÿG AúKq A!kAI A:kAIr AÛkAIrr ! @ \rA! A!@  j" ( k" A7"AÿM@ A F\r A F\r A kAO\r  @@@  jAm"AtA°j("Au j"\nAtA°j(Aÿÿÿq K@ \nAk!   AvAq j"AtA°j(AÿÿÿqM\r Aj!  N\r  \nAN\r A!Aä! A7"AÿM@ AÿG AúKq A!kAI A:kAIr AÛkAIrr  @@@  jAm" AtAÀ:j("Au j"\nAtAÀ:j(Aÿÿÿq K@ \nAk!   AvAq j"AtAÀ:j(AÿÿÿqM\r Aj!  N\r A!\n \nAN ! !  Aq "E\r @@ (x" (|"N@ AÀ Av j AL"6| (t Als"\rA! ($"\rE\rAå (, \r  Aj6x (t"E\r  6t (x"Aj6x  Alj" : A$: B7  6  6  A F\r A F\r A\rkA}K\r AÿG AúKq A!kAI A:kAIr AÛkAIrr ! @ E\rA! A!@  j" ( k" A7"AÿM@ A F\r A F\r A kAO\r  @@@  jAm"AtA°j("Au j"\nAtA°j(Aÿÿÿq K@ \nAk!   AvAq j"AtA°j(AÿÿÿqM\r Aj!  N\r  \nAN\r A!Aä! A7"AÿM@ AÿG AúKq A!kAI A:kAIr AÛkAIrr  @@@  jAm" AtAÀ:j("Au j"\nAtAÀ:j(Aÿÿÿq K@ \nAk!   AvAq j"AtAÀ:j(AÿÿÿqM\r Aj!  N\r A!\n \nAN ! !  Aq "E\r @@ (x" (|"N@ AÀ Av j AL"6| (t Als"\rA! ($"\rE\rAå (, \r  Aj6x (t"E\r  6t (x"Aj6x  Alj" : Aþ: B7  6  6  A F\r A F\r A kAM\r !  A! ! AqE\r @@ (x" (|" N@ AÀ Av j AL"6| (t Als" \rA! ($"\rE\rAå (, \r  Aj6x (t" E\r  6t (x"Aj6x Alj" : Aþ: B7  \n6  6  @@  (F\r Q"AÿK@A!A!@@@  jAm" AtA°j("Au j"\nAtA°j(Aÿÿÿq K@ \nAk!   AvAq j"AtA°j(AÿÿÿqM\r Aj!  N\r !  \nAN\r !  A F\r A F\r A kAM\r !  A! ! AqE\r\r @@ (x" (|" N@ AÀ Av j AL"6| (t Als" \rA! ($"\rE\rAå (, \r  Aj6x (t" E\r  6t (x"Aj6x Alj" : A+: B7  6  6 \r @@  (F\r Q"AÿK@A!A!@@@  jAm" AtA°j("Au j"\nAtA°j(Aÿÿÿq K@ \nAk!   AvAq j"AtA°j(AÿÿÿqM\r Aj!  N\r !  \nAN\r !  A F\r A F\r A kAM\r !  A! ! AqE\r @@ (x" (|" N@ AÀ Av j AL"6| (t Als" \rA! ($"\rE\rAå (, \r  Aj6x (t" E\r  6t (x"Aj6x Alj" : A=: B7  6  6 A F\r A F\r A kAM\r !  A! ! AqE\r @@ (x" (|" N@ AÀ Av j AL"6| (t Als" \rA! ($"\rE\rAå (, \r  Aj6x (t" E\r  6t (x"Aj6x Alj" : AÞ: B7  6  6 @ Aj" O\r -A?G\rA!@ (ì" M@ !  !  \nAkO\r  Aj" \n \nI"M@  j/A¿üF\r@@ Aj! Aj" K\r " j/A¿üG\r  !  \nI Aj"Kq  Atj"(! (!  6ì ( ! @ M\r -A!G\r  j-AßqAÁkAÿqAK\r@ Aj" O\r@  j-AßqAÁkAÿqAK\r Aj" G\r ! A! (ð" K  \nAkOq\r Aj" \n \nI"M@  j-A>F\r@@ Aj! Aj" K\r " j-A>G\r  !  \nI Aj" Kq  Atj"(! (!  6ð ( ! @ A j" O\r )B¼ÂìšÄ¨ªÁ… 1Bۅ„BR\rA! (ô" K  \nAkOq\r@ Aj" \n \nI" M@  j"/Aݺs -A>srE\r@@ Aj! Aj" K\r  "j"/Aݺs -A>sr\r  !  \nI Aj"Kq@  Atj"(! (!  6ô ( !\n ! Aj" \nO\r@ Aj" \nO\r  j-" A0kAÿqA\nIA AßqAÁkAÿqAI E\r@  j-"A0kAÿqA\nI\r AßqAÁkAÿqAI\r A+k"AK\r AF\r Aj" \nF\r@  kA K\r  j-" A:F@  \nO\r@  j-" A k"AMAA tA€€q\r A>G@ A I\r AG\r  j-A-F\rAð! Aj !@@ (x" (|"N@ AÀ Av j AL"6| (t Als"\rA! ($"\rE\rAå (, \r  Aj6x (t"E\r  6t (x"Aj6x  Alj" Ar: A<: B7  6  6@@ (x" (|"N@ AÀ Av j AL"6| (t Als"\rA! ($"\rE\rAå (, \r  Aj6x (t"E\r  6t (x"Aj6x  Alj" Ar: A>: B7  6  Ak6 (t (x"Alj"A k Ak6 Ak Ak6 ! !   6 @@ (x" (|"N@ AÀ Av j AL"6| (t Als"E\r 6t (x"Aj6x  Aj6x (t"E\r\n  Alj"A¼(; B7  6  6@ (x" (|"N@ AÀ Av j AL"6| (t Als"E\r 6t (x"Aj6x  Aj6x (t"E\r\n ( !  Alj"A¾0; B7  6  6 (t (x"Alj"A k Ak6 Ak Ak6A! !  (M\r@@   jAv"Atj"( K@ E@ ! \n   AtjAk(K@ ! \n Ak!  ( O@ ! Aj!  M\r A!  ($"E\rAå (,   Aj!  A F\r A F\r A\rkA}K\r AÿG AúKq A!kAI A:kAIr AÛkAIrr "! As! A! @  \nF\rA!A!@@  \nj" ( \nk"A7"AÿM@ A G\r  @@@  jAm"AtA°j(" Au j" AtA°j(Aÿÿÿq K@ Ak!   AvAq j"AtA°j(AÿÿÿqM\r Aj!  N\r  A! AH\r  A F\r A kAI\r A!Aä!AA  A7"AÿM@ AÿG AúKq A!kAI A:kAIr AÛkAIrr  @@@  jAm"AtAÀ:j(" Au j" AtAÀ:j(Aÿÿÿq K@ Ak!   AvAq j"AtAÀ:j(AÿÿÿqM\r Aj!  N\r A! AN "! As! ! \n!A   q AßFq""A " rE\r  kAp!@@ (x" (|"N@ AÀ Av j AL"6| (t Als"\rA! ($"\rE\rAå (, \r  Aj6x (t"\r  6t (x"Aj6x  Alj" AtA# AG  MqAA  OA r" AFrA@k:  : B7  \n6  6 ! \n "M\r@@@ (x" (|"N@ AÀ Av j AL"6| (t Als"\rA! ($"\rE\r Aå (, \r Aj6x (t"\r  6t (x"Aj6x  Alj"AÄ; B7  6  6 Aj" \nI\r ! \n! @@ (x"\r (|"N@ AÀ Av j AL"6| (t Als"\rA! ($"\rE\rAå (, \r  \rAj6x (t"E\r  6t (x"\rAj6x (!  \rAlj"Aÿ ; B7  6  6A!  A! Aj$@ " \r A (xA¿AM@ (à"AN@ Ak! A€j! AØj! A j!@ (t" Al"j" (!\r@ -"AÄF\r ( !\nA! A! \rAN@   \rAlj" ( Alj! \nAl! (! -A q@ A!: Ak"6A!!  j!  I@ ( I\r  I@ ( I\r @  I@ A!G\r  AÛG\r ( A€€ÀqE\r (" (O\r ( j-AÞG\r Aj"6 (t j"(" M\r  ( j  kN"E\r ( "E@ (pAj"6p  6  (Aj6 6 (6 -A”r:  -A˜r: (! (! (  @@@@ -\rA qE\r -AÛG\r E\r (" ("kAG\r -AÛG\r E\r ( ("kAG\r -AÝG\r  AkG\r ( ("kAG\r  (AjG\r@@ Aj" \nN"@ !  (t! !@@  Alj" -"AÄF\r AüF\r ( kAäK\r -AqE\r ( ! Aj" \nH\r A!  (" F\r  kAäK\r  I@ (!@@  j-A\nk Aj" G\r A!@   Atj"("L@ (t!\r@ \r Alj( " N\r  6  ("L@ (t!\r@ \r Alj( " N\r  6 Aj"AG\r @@ ( (I@@  L\r  kAk! (t!\rA!  AsjAq"@@ \r AljAÄ; Aj! Aj" G\r AI\r@ \r Alj"AÄ;L AÄ;8 AÄ;$ AÄ; Aj" G\r -Ar: (6  @ \r \n kAk! (t!\rA! \n AsjAq"@@ \r AljAÄ; Aj! Aj" G\r AI\r@ \r Alj"AÄ;L AÄ;8 AÄ;$ AÄ; Aj" \nG\r  (6 (6  (6 (t"\r j" \n6 \r j"\r 6  -Ar: \r \r-Ar: (! (!  Aj \nO (  (6  (6 (t"\r j" \n6 \r j"\r 6  -Ar: \r \r-Ar: (! (! (  \r (!  (" ("G\r ( AjK@ -AÀq\r    ( AjP  -AÀq\r   (  AjP "AH\r E\r  (6 (t \rAlj(!\r  @  ("O\r (" j-A(G\r \nAj! A! !@@@   jAv"Atj"( K@ E\r  AtjAk( I\r Ak!   (M\r Aj!  O\r A! @@ Aj"  Atj(" I@@  j-A k"AK\rA tA€€qE\r Aj" G\r !  6@  O\r  j-A\nk Aj" O\r  Atj(!  6 @  O\r  j-A)G\rA! A6 B7  6  6 Aj! A    Atj"(" Aj Aj 8E\r@   k ( Aj A j A,j A(j A$j9@ ( " j! (," F!   j"Atj(! (!   ("6(  6$A!A! @  I@@  j-"A k"AK\rA tA€€qE\r Aj" G\r Aj" O\r   Atj("j-! AÿqA)G\r  Aj" 6 ($" (("M@A! A6 B7A   k! @ A6  6   j"6A  @ q"@  Atj!A! !@   Atj("  K" KA!  "kAq"@@  ( j-: Aj! Aj! Aj" G\r  kA|M@@  ( j-:  ( j-:  ( j-:  ( j-: Aj! Aj" G\r   O\r A\n: Aj!  Aj"Atj(! ($" E\rAÔ (,   A6  6   k6 (! A ! (x" L@  6  (t! !@  Alj"(K@@ -AqAG\r  ( "Alj( I\r \r r  Aj" H\r  6  L\r  \nkAk! (t! A!  \nAsjAq"@@ AljAÄ; Aj! Aj" G\r AI\r@ Alj"AÄ; AÄ;L AÄ;8 AÄ;$ Aj" G\r  -AÀq\r   ( ( AjP"AH\r E\r -Ar:  -Ar: Aj" (tj (6 (t j ( 6  (tj (6( Aj! (t! (@  Alj (Ð6 6Ð  Alj (6 (! (! -!  Aj \nO   AÛF"!   !   !   ! ! / AŒqE\r@@ "Aj! -$"AÄG" \r  I\r À! !@@ "\nAk! \r  K\r -%" AqE\r E\r ( (G\rA÷ ATE\r (  (tkAmG\r \nAk( (G\r AÄ:$  Aïq:% \nAkAÄ: \nAk" -Aïq: \r "AN\r B7à A6¸ @A! A6Ô (x"AL\r (t!\rA!@@ \r Alj"-"Aq\r -AüG\r ( (kAG\r A6  Ar:@ (ØAH@ 6Ø  \r (ÜAlj 6 6Ü Aj"6Ô Aj" G\r A!  A! A (xO  A! A0j$ Þ#Aðk"$ B7h B7` B7X B7P B7H B7@ B78 B70 A6( B7 B7 B7 B7A! @    Aj AÐj<\r  A Aj A0j<\r  6( (,! @  Aj (" E@A!  ($"E\rA (,    Aj (" E@A!  ($"E\rAæ (,  (`@ (Pr (Tr (Xr (@@ (0r (4r (8r Aðj$ Ý@ ( " ("I@ (!  ( Av jA "At"s"E@A ($"E\rAå (, A  6 ( Ajs"E@A ($"E\rAå (, A  6  6 ( ! ( Atj 6  ( Atj 6  ( Aj6 A Ü Aj!@@@ Aj" O\r j-A#G\r j-A rAøG\r !@@@@ j-"A0kAÿqA\nI\r AÁkAÿqAI\r  kAK\r AákAÿqAI\r   kAK\r Aj" G\r !  F\r  kAI\r  @ Aj" O"\r j-A#G\r !@@  kAK\r j-A0kAÿqA K\r Aj" G\r !  F\r  kAI\r   M\r j-AßqAÁkAÿqAK\r  \r@@ j-"AßqAÁkAÿqAO@   kA0K\r A0kAÿqA\nI\r    kA0M\r   Aj" G\r  " kAkA.K\r  M\r j-A;G\rA!  Aj6  ³#Ak"$@@  O\r (!@  j-A k"AK\rA tA€€qE\r Aj" G\r !   O\r (!@  jAk-A k"AK\rA tA€€qE\r Ak" K\r !  6  6  6@  Aj (, ("@ ($"E\rAŠ (,   AjA?"\r  Aj (, ("E@A!  ($"E\rA¯ (,  Aj$  Ê"#A0k"\r$  H@ A¸j! A€j! \rAr! \rAr! (!@@ (t" Al" j"-"Aq@ AqE\r@ E\r ,"E\r  `\r ( !  ,"\nAÿq"E\r  \n`E\r (" I\r@@@@@@@@@@@@@@@@@ A!k^  (! Aq@ AN@  Alj" -AÀr:  6  6  AH\r  Alj"( 6¸  6  6@ (ä" AN@  Alj 6  6à 6ä A6  Aj" (xN\r  Alj"-A;G\r (  (" \rKE\r  6  6  Ar:  -Ar:  6  AqE\r \r A€A˜ \nA*Fj"A j6 AÀq" AÀF@ ! A  \r Aj6 A€F\r ! A ! Aj6A! A°A´ ( kAFj!\n@ AqE\rA! \n("AH\r@   Atj"\n("L@@  Alj( " N\r \n 6  \n("L@@  Alj( " N\r \n 6 Aj" AG\r  Alj" 6  6  -Ar:  -Ar: \r AqE\r  \n(6 \n 6 @ AqE\rA! (Ä"AH\r@   Atj"\n("L@@  Alj( " N\r \n 6  \n("L@@  Alj( " N\r \n 6 Aj" AG\r  Alj" 6  6  -Ar:  -Ar: AqE\r  (Ä6 6Ä @ AqE\r (¼"AH\rA!  Alj" ( (k ( kG\r@   Atj"\n("L@@  Alj( " N\r \n 6  \n("L@@  Alj( " N\r \n 6 Aj" AG\r @ Aj" N\r  kAk!A!  AsjAq"\n@@  AljAÄ; Aj! Aj" \nG\r AI\r@  Alj" AÄ;L AÄ;8 AÄ;$ AÄ; Aj" G\r 6  6 -Ar:  -Ar: A6¼ AqE\r\n  (¼6 6¼ \n  Aj"Al"j"(! (! \r 6 \r ("6, \r 6( \r 6$ \nAÀF@   \rAAAA˜ \rA(jRAL\r\n \r(!  O\r Q" AÿM\rA!A!@@@  jAm" AtA°j("Au j"AtA°j(Aÿÿÿq K@ Ak!  AvAq j"AtA°j(AÿÿÿqM\r Aj!  N\r  AN\r  ( kAG\r@ AqE\rA! (À"AH\r@   Atj"\n("L@@  Alj( " N\r \n 6  \n("L@@  Alj( " N\r \n 6 Aj" AG\r  Alj" 6  6  -Ar:  -Ar: AqE\r  (À6 6À  ( kAG\r@ AqE\rA! (È"AH\r@   Atj"\n("L@@  Alj( " N\r \n 6  \n("L@@  Alj( " N\r \n 6 Aj" AG\r  Alj" 6  6  -Ar:  -Ar:  AqE\r  (È6 6È  ( kAG\r@ AqE\rA! (Ì"AH\r@   Atj"\n("L@@  Alj( " N\r \n 6  \n("L@@  Alj( " N\r \n 6 Aj" AG\r  Alj" 6  6  -Ar:  -Ar:  AqE\r  (Ì6 6Ì  A! A!  A F\r A F\r A kAI\r ( jAk,"@Aã AT\r \r((" I\r Ak!@@@ -AÄF\r ( K\r  (O\r -" Aq\r Ak" O\r  AqE\r   \rA,jAA.AAØ \rA$jRAH\r \r(,! @ \nAÀF\r@ O\r (" j-A/G\r Aj  \rA,jAA/AùA \rA$jRAH\r \r(," O\r  j-A/G\r \r Aj" 6, @ O\r ( j-A?G\r Aj  \rA,jAA&AóA• \rA$jRAH\r \r(,! O\r ( j-A#G\r Aj  \rA,jAAAAÛ \rA$jRAH\r \r(,! @ O\rA!A!@ ( j" ( kA7"AÿM@ A F\r A F\r A kAO\r  @@@  jAm" AtA°j("Au j"AtA°j(Aÿÿÿq K@ Ak!   AvAq j"AtA°j(AÿÿÿqM\r Aj!  N\r  AN\r ,"@A¡ A T\r \r($"  (xAlj"O\r@@@ -AÄF\r ( M\r ( K\r -"Aq\r Aj" I\r  AqE\r  6  6  \n:  6  6 (t" j" 6  j" 6  -Ar:  -Ar:  \r Atr 6 A q! Aj! AàqAàG@ \r Atj Aj6 Aj! As AGqE@ \r Atj Aj6 Aj!  \r(("AljA AN"! A !@ \r(("AH\r  Alj! @ ( (M\r ! ! @ AF\r@ \r(("AH\r  Alj! @ ( (M\r ! ! AF\r@ \r( ("AH\r  Alj! @ ( (M\r ! ! AF\r@ \r(("AH\r  Alj! @ ( (M\r ! ! AF\r \r((" AH\r  Alj! @ ( (M\r ! ! E\r (! (! (! !\n@@@@@@  Alj"-"A!k\n AÛk A€A˜ A*Fj -"AtAuA qj!\n@ AvAk \nAj!\n  A°A´ ( (kAFj!\n  \nAj!\n @ k" k"K@  (" (k k j"Al" j" (6  )7  )7  k"6  6 (t j \n(6 \n 6  O\r  Alj j" (6  )7  )7  k j"6  6 A!\n@   \nAtj"("L@@ AN@  (t Alj( "6  N\r \nAj"\nAG\r (t" Alj" 6  j" 6  -Ar:  -Ar:  AqE\r A€A˜ \nA*Fj AtAuA qj!@@@ AvAk Aj!  Aj!  (6  6 -"AqE\r Aq@ (t ( Alj(!  (! Aj" H\r \rA0j$ –#Ak"$@ (E\r  6! (  (pAtj("E@A!  @  ("I\r   ( (ljO\r  (F@ ( (  DE\r A!   6  6  6  Aj6 Aj!@ ("@@   Av"Atj"G"AH@   E\r Aj!  Asj "\r A! E@A!  (! Aj$  ý#A k"$ Aß: A¦Ô;A! ( "A€ q@ A$:A! A€€€q@ Aj rA=: Aj! A€€€q@ Aj rA+: Aj! A€€q@ Aj jAü: Aj! A€€q@ Aj jAÞ: Aj! A€„q@ Aj jAþ: Aj! A! Aj jA:    AjAM ( "AŒq@ Aq@ AÀ:A! Aq@  rA:: Aj! A€q  rA.: Aj  rA:     AjM A€jAÿAÐü A j$ • (TE@A Ak! Ak!AA ("\n j-A!F j!A!@@@   jAv"Atj" ( K@ E\r  AtjAk( I\r Ak!   (M\r Aj!  O\r A! @  ("M" E@@  kq"@ !@    K" KA!  "kAq"\n@@  ( j-: Aj! Aj! Aj" \nG\r  kA|M@@  ( j-:  ( j-:  ( j-:  ( j-: Aj! Aj" G\r   O\r A : Aj! Aj" Atj"(! (! A! ($"E\rAÔ (, A  k   \nj!  k ! A  Aj60A! Aj !\nA!@@ \n("E\r Aj p"AH\r   kK\r \nAj!\n  j" I\r A=! AH\r A \r  l E@A!  A! (0!\n@ \n(" E\r Aj p" j" K\r Aj h \nAj!\n  K\r A \r  A€Àsl \r   \rH!   AHq\r A=! +0 \r  m"AN\r \n -!\n Aj! \r E\rA!@  Atj("\n@  Atj \n jA! Aj"A\nG\r A\nO@A! \n @  Atj(\rA! Aj"A\nG\r A!   :\'A! ! !   k"  H" AÿÿÿÿsJ\rA=! \r  j"  \rH" \nK\r A   l  h A0   A€€sl A0  Al h A   A€Àsl ( Ak" O\r B€”ëÜT\r Ak" > @ "I@ Ak"(E\r (, k"6, ! AJ\r AH@ AjA nAj! AæF!@A A k" A O!\n@  M@AA (!  A€”ëÜ \nv!\rA \ntAs!A! !@  (" \nv j6  q \rl! Aj" I\r AA (! E\r  6 Aj! (, \nj"6,   j" " Atj   kAu J! AH\r A!@  M\r  kAuA l!A\n! ("A\nI\r@ Aj!  A\nl"O\r A AæGk AçF AGqk"  kAuA lA kH@ A0jA„`A¤b AHj A€Èj"A m"\rAtj!\nA\n!  \rA lk"AL@@ A\nl! Aj"AG\r @ \n("  n" lk"\rE \nAj" Fq\r@ AqE@D@C! A€”ëÜG\r \nO\r \nAk-AqE\r D@C! Dà?Dð?Dø?  FDø? \r Av"F \r I!@ \r -A-G\r š! š! \n  \rk"6    a\r \n  j"6 A€”ëÜO@@ \nA6 \nAk"\nK@ Ak" A6 \n \n(Aj"6 Aÿ“ëÜK\r  kAuA l!A\n! ("A\nI\r@ Aj!  A\nl"O\r \nAj"   K! @ " M"E@ Ak"(E\r @ AçG@ Aq!\r  AsA A " J A{Jq"\n j! AA~ \n j! Aq"\r\rAw!@ \r Ak("\nE\rA\n!A! \nA\np\r@ "\rAj! \n A\nl"pE\r \rAs!  kAuA l! A_qAÆF@A!\r  jA k"A AJ"  J!  A!\r  j jA k"A AJ"  J! A!\n AýÿÿÿAþÿÿÿ \rr"J\r AGjAj!@ A_q"AÆF@  AÿÿÿÿsJ\r A AJ!    Au"s k­ k"kAL@@ Ak"A0:  kAH\r Ak" : AkA-A+ AH:  k" AÿÿÿÿsJ\r  j" AÿÿÿÿsJ\r A   j" l  h A0   A€€sl@@@ AÆF@ AjA r!  K"! @ 5 k!@  G@  AjM\r@ Ak"A0:  AjK\r   G\r Ak"A0:   kh Aj" M\r @ AùAh  M\r AL\r@ 5 k" AjK@@ Ak"A0:  AjK\r A A Nh A k! Aj" O\r A J! ! \r  @ AH\r  Aj  K!\n AjA r! !@  5 k"F@ Ak"A0: @  G@  AjM\r@ Ak"A0:  AjK\r  Ah Aj! \rrE\r AùAh   k"  Hh k! Aj" \nO\r AN\r A0 AjAAl   kh  ! A0 A jA Al A   A€Àsl    J!\n   AtAuA qj!@ A K\rA k!D0@!@ D0@¢! Ak"\r -A-F@  š ¡ š!     ¡!  (," Au"s k­ k"F@ Ak"A0: (,! Ar!\r A q! Ak" Aj: AkA-A+ AH: AqE ALq! Aj!@ " ü"AÐÑj- r:  ·¡D0@¢!@ Aj" AjkAG\r Da q\r A.: Aj! Db\r A!\n Aýÿÿÿ \r  k" j"kJ\r A   Aj  Ajk" Ak H  "j" l  \rh A0   A€€sl Aj h A0  kAAl  h A   A€Àsl    J!\n A°j$ \n ¹~  (AjAxq"Aj6 )! )!#A k"$ Bÿÿÿÿÿÿ?ƒ!~ B0ˆBÿÿƒ"§"AøkAýM@ B† B<ˆ„! A€øk­!@ Bÿÿÿÿÿÿÿÿƒ"B€€€€€€€Z@ B|!  B€€€€€€€€R\r Bƒ |! B  BÿÿÿÿÿÿÿV"! ­ |  @  „P\r BÿÿR\r B† B<ˆ„B€€€€€€€„!Bÿ  Aþ‡K@B!Bÿ  A€øAø P"\n" k" AðJ@B!B   B€€€€€€À„ \n!A!\n G@ Aj! ! !@A€ k"AÀq@  A@j­†!B!  E\r  ­"† AÀ k­ˆ„!  †! 7 7 ) )„BR!\n @ AÀq@  A@j­ˆ!B!  E\r AÀ k­†  ­"ˆ„!  ˆ!  7  7 )B† )"B<ˆ„!@ \n­ Bÿÿÿÿÿÿÿÿƒ„"B€€€€€€€Z@ B|!  B€€€€€€€€R\r Bƒ |! B€€€€€€€…  BÿÿÿÿÿÿÿV"! ­ ! A j$ B€€€€€€€€€ƒ B4†„ „¿9 ¦ (T"(! (" ( ("k"  I"@   V  ( j"6  ( k"6    K"@   V  ( j"6  ( k6 A: (,"6 6  ¢ E@A @  AÿM\r@AìÞ((E@ A€qA€¿F\rAÐÝA6  AÿM@ A?qA€r: AvAÀr:A  A€@qA€ÀG A€°OqE@ A?qA€r: A vAàr: AvA?qA€r:A  A€€kAÿÿ?M@ A?qA€r: AvAðr: AvA?qA€r: A vA?qA€r:A  AÐÝA6 AA  :A Ñ( #Ak"\n$@@@@@@@@@@ AôM@Aß("A A jAøq A I"Av"v"Aq@@ AsAq j"At"A¸ßj" (À_"("F@Aß A~ wq6   6 6 Aj!  Ar6  j" (Ar6 A˜ß("M\r @@ tA t"A krqh"At"A¸ßj" (À_"("F@Aß A~ wq"6   6  6 Ar6 j"  k"Ar6 j 6 @ AxqA¸ßj!A¤ß(! A Avt"qE@Aß  r6   ( !  6  6  6  6 Aj!A¤ß 6A˜ß 6 A”ß(" E\r hAt(Àa"(Axq k! !@@ ("E@ ("E\r (Axq k"   K"!  ! !  (!  ( "G@ (" 6 6 \n (" Aj ("E\r Aj !@ ! "Aj! ("\r Aj! ("\r A6 A! A¿K\r A j"Axq!A”ß(" E\rA! AôÿÿM@ A& Avg"kvAq AtkA>j! A k!@@@ At(Àa"E@A!  A! A AvkA AGt!@@ (Axq k" O\r ! "\rA! !  ("   AvAqj("F ! At! "\r rE@A!A t"A kr q"E\r hAt(Àa! E\r @ (Axq k" I!   !  ! ("  ( "\r E\r A˜ß( kO\r (!  ( "G@ (" 6 6  (" Aj ("E\r Aj !@ ! "Aj! ("\r Aj! ("\r A6  A˜ß("M@A¤ß(!@ k"AO@  j" Ar6 j 6  Ar6   Ar6 j" (Ar6A!A! A˜ß 6A¤ß 6 Aj! Aœß("I@Aœß  k"6A¨ßA¨ß(" j"6  Ar6 Ar6 Aj! A! A/j"Aèâ(@Aðâ(  AôâB7AìâB€ €€€€7Aèâ \nA jApqAتժs6AüâA6AÌâA6A€ "j"A k"q" M\rAÈâ("@AÀâ(" j" M\r  I\r @AÌâ-AqE@@@@@A¨ß("@AÐâ!@ (" M@   (jI\r ("\r Au"AF\r !Aìâ("Ak" q@  k  jA kqj!  O\rAÈâ("@AÀâ(" j" M\r I\r u" G\r   k q"u" ( (jF\r ! AF\r A0j M@ !  Aðâ("  kjA kq"uAF\r  j! !  AG\r AÌâAÌâ(Ar6 u!Au! AF\r AF\r M\r k" A(jM\r AÀâAÀâ( j"6AÄâ( I@AÄâ 6 @A¨ß("@AÐâ!@  (" ("jF\r ("\r  A ß("A ME@A ß 6 A!AÔâ 6AÐâ 6A°ßA6A´ßAèâ(6AÜâA6@ At" A¸ßj"6À_  6Ä_ Aj"A G\r Aœß A(k"Ax kAq"k"6A¨ß  j"6  Ar6 jA(6A¬ßAøâ(6   O\r  I\r ( Aq\r  j6A¨ß Ax kAq"j"6AœßAœß( j" k"6  Ar6  jA(6A¬ßAøâ(6  A!  A!  A ß( K@A ß 6  j!AÐâ!@@  ("G@ ("\r  - AqE\r AÐâ!@@ (" M@   (j"I\r (!  Aœß A(k"Ax kAq"k"6A¨ß  j"6  Ar6 jA(6A¬ßAøâ(6  A\' kAqjA/k" AjI"A6 AØâ)7 AÐâ)7AØâ Aj6AÔâ 6AÐâ 6AÜâA6 Aj!@ A6 Aj! Aj!  I\r  F\r  (A~q6   k"Ar6  6 AÿM@ AøqA¸ßj!Aß("A Avt"qE@Aß  r6  ( ! 6  6 A !A  A! AÿÿÿM@ A& Avg"kvAq AtrA>s!  6 B7 AtAÀáj!@@A”ß("A t"qE@A”ß  r6  6  6  A AvkA AGt! (!@ "(Axq F\r Av! At!  Aqj"("\r  6  6 A! ! !A  (" 6  6  6A!A!A j 6  j 6 Aœß(" M\rAœß k"6A¨ßA¨ß(" j"6  Ar6 Ar6 Aj!  AÐÝA06A!  6 ( j6 Ax kAqj" Ar6 Ax kAqj"  j"k!@A¨ß( F@A¨ß 6AœßAœß( j"6  Ar6  A¤ß( F@A¤ß 6A˜ßA˜ß( j"6  Ar6  j 6  ("AqAF@ Axq! ( !@ AÿM@ (" F@AßAß(A~ Avwq6  6  6  (!@  G@ (" 6  6  @ (" Aj ("E\r Aj !@ ! "Aj! ("\r Aj! ("\r A6  A! E\r@ ("At"(Àa F@ AÀáj 6 \rA”ßA”ß(A~ wq6  @  (F@  6   6 E\r  6 ("@  6  6 ("E\r  6  6  j"(!  j!  A~q6  Ar6  j 6 AÿM@ AøqA¸ßj!Aß("A Avt"qE@Aß  r6   ( !  6  6  6  6  A! AÿÿÿM@ A& Avg"kvAq AtrA>s!  6 B7 AtAÀáj!@@A”ß("A t"qE@A”ß r6  6  6  A AvkA AGt! (!@ "(Axq F\r Av! At!  Aqj"("\r  6  6  6  6  (" 6  6 A6  6  6 Aj!  @ E\r@ ("At"(Àa F@ AÀáj 6 \rA”ß A~ wq" 6  @  (F@  6   6 E\r 6 ("@ 6  6 ("E\r 6  6 @ AM@   j"Ar6 j" (Ar6   Ar6  j" Ar6  j 6 AÿM@ AøqA¸ßj!Aß("A Avt"qE@Aß  r6  ( ! 6  6  6  6  A! AÿÿÿM@ A& Avg"kvAq AtrA>s!  6 B7 AtAÀáj!@@ A t"qE@A”ß  r6  6  6  A AvkA AGt! (!@ "(Axq F\r Av! At!  Aqj"("\r  6  6  6  6  (" 6  6 A6  6  6 Aj!  @ E\r@ ("At"(Àa F@ AÀáj 6 \rA”ß A~ wq6  @  (F@ 6  6 E\r 6 ("@ 6  6 ("E\r 6  6 @ AM@   j"Ar6 j" (Ar6   Ar6  j" Ar6  j 6 @ AxqA¸ßj!A¤ß(!A Avt" qE@Aß  r6   ( !  6  6 6 6 A¤ß 6A˜ß 6 Aj! \nAj$ ‚ @ E\r Ak" Ak("Axq"j!@ Aq\r AqE\r  ("k"A ß(I\r j!@@@A¤ß( G@ ( ! AÿM@  ("G\rAßAß(A~ Avwq6  (!  G@ (" 6  6  (" Aj ("E\r Aj !@ ! "Aj! ("\r Aj! ("\r A6  ("AqAG\rA˜ß 6  A~q6  Ar6  6  6  6  A! E\r@ ("At"(Àa F@ AÀáj 6 \rA”ßA”ß(A~ wq6  @  (F@  6   6 E\r  6 ("@  6  6 ("E\r  6  6  O\r ("AqE\r@@@@ AqE@A¨ß( F@A¨ß 6AœßAœß( j"6  Ar6 A¤ß(G\rA˜ßA6A¤ßA6 A¤ß(" F@A¤ß 6A˜ßA˜ß( j"6  Ar6 j 6 Axq j! ( ! AÿM@ (" F@AßAß(A~ Avwq6   6  6  (!  G@ (" 6  6  (" Aj ("E\r Aj !@ ! "Aj! ("\r Aj! ("\r A6   A~q6  Ar6 j 6  A! E\r@ ("At"(Àa F@ AÀáj 6 \rA”ßA”ß(A~ wq6  @  (F@  6   6 E\r  6 ("@  6  6 ("E\r  6  6  Ar6 j 6  G\rA˜ß 6 AÿM@ AøqA¸ßj!Aß("A Avt"qE@Aß r6   ( !  6 6  6  6 A! AÿÿÿM@ A& Avg"kvAq AtrA>s!  6 B7 AtAÀáj!@A”ß("A t"qE@A”ß  r6  6A!A  A AvkA AGt! (!@ "(Axq F\r Av! At!  Aqj"("\r  6A! !A ! !   (" 6  6A!A!A !  j 6  6 j 6A°ßA°ß(Ak"A 6 ‰  E@ q A@O@AÐÝA06A A A jAxq A I! Ak"("Axq!@ AqE@ A€I\r Aj M@ !  kAðâ(AtM\r A   j!@  O@  k"AI\r   AqrAr6  j" Ar6  (Ar6  t  A¨ß( F@Aœß( j" M\r   AqrAr6  j"  k"Ar6Aœß 6A¨ß 6  A¤ß( F@A˜ß( j" I\r@  k"AO@   AqrAr6  j" Ar6  j" 6  (A~q6   Aq rAr6  j" (Ar6A!A! A¤ß 6A˜ß 6  ("Aq\r Axq j"\n I\r \n k! ( !@ AÿM@ (" F@AßAß(A~ Avwq6   6  6  (! @  G@ (" 6  6  @ (" Aj ("E\r Aj !@ ! "Aj! ("\r Aj! ("\r A6  A! E\r@ ("At"(Àa F@ AÀáj 6 \rA”ßA”ß(A~ wq6  @  (F@ 6  6 E\r  6 ("@  6  6 ("E\r  6  6 AM@  Aq \nrAr6  \nj" (Ar6    AqrAr6  j" Ar6  \nj" (Ar6  t !  "@ Aj q"E@A  A|Ax Ak("Aq Axqj"   KV r  «  j!@@ ("Aq\r AqE\r (" j!@@@ k"A¤ß(G@ ( ! AÿM@  ("G\rAßAß(A~ Avwq6  (! G@ (" 6  6  (" Aj ("E\r Aj !@ ! "Aj! ("\r Aj! ("\r A6  ("AqAG\rA˜ß 6  A~q6 Ar6  6  6  6  A! E\r@ ("At"(Àa F@ AÀáj 6 \rA”ßA”ß(A~ wq6  @ (F@  6   6 E\r  6 ("@  6  6 ("E\r  6  6 @@@@ ("AqE@A¨ß( F@A¨ß 6AœßAœß( j"6 Ar6 A¤ß(G\rA˜ßA6A¤ßA6 A¤ß(" F@A¤ß 6A˜ßA˜ß( j"6 Ar6 j 6 Axq j! ( ! AÿM@ (" F@AßAß(A~ Avwq6   6  6  (!  G@ (" 6  6  (" Aj ("E\r Aj !@ ! "Aj! ("\r Aj! ("\r A6   A~q6 Ar6 j 6  A! E\r@ ("At"(Àa F@ AÀáj 6 \rA”ßA”ß(A~ wq6  @  (F@  6   6 E\r  6 ("@  6  6 ("E\r  6  6 Ar6 j 6 G\rA˜ß 6 AÿM@ AøqA¸ßj!Aß("A Avt"qE@Aß  r6   ( !  6  6 6 6 A! AÿÿÿM@ A& Avg"kvAq AtrA>s! 6 B7 AtAÀáj!@@A”ß("A t"qE@A”ß  r6  6 6  A AvkA AGt! (!@ "(Axq F\r Av! At!  Aqj"("\r  6 6 6 6 (" 6  6 A6 6 6 W~@ ­B|BøÿÿÿƒAÄÜ("­|"BÿÿÿÿX@ §"?AtM\r \r AÐÝA06A AÄÜ 6  ² #Ak"$  6 @ AÓM@AàÑA Ó A jx(!  A|O@y  AÒn"AÒl"k6A ÓAàÔ Ajx"( j! A ÓkAu!@A!@@@ "A/F\r At(àQ"n" I\r Aj!  lG\r A/I\r AÓ!@ n" I\r  lF\r A\nj"n" I\r  lF\r A j"n" I\r  lF\r Aj"n" I\r  lF\r Aj"n" I\r  lF\r Aj"n" I\r  lF\r Aj"n" I\r  lF\r Aj"n" I\r  lF\r A$j"n" I\r  lF\r A(j"n" I\r  lF\r A*j"n" I\r  lF\r A.j"n" I\r  lF\r A4j"n" I\r  lF\r A:j"n" I\r  lF\r A`-_.-+_\\\\({[,"children":[NANINFcatching a class without an object?)}].!?,;mailto:,"content":h6h5h4h3h2h1http://Too many link reference definition instantiations.Unsupported abi_version.Aborted from text() callback.Aborted from enter_span() callback.Aborted from leave_span() callback.Aborted from enter_block() callback.Aborted from leave_block() callback.malloc() failed.realloc() failed.@:..!#$%&\'*+/=?^_`{|}~-_.:-+-.-_+-_*(null)Suppressing too sparse table (see https://github.com/mity/md4c/issues/345)._=().+-_~%false && "unhandled NodeType in nodeTypeToString"\\"{"type":"[]!xX \n™Jìi¿e£<‡ ¢°üOs{±2‡+F< ÂÎ._VÉšAÜ ~ô H, „*NSt3__220__shared_ptr_emplaceIN8Markdown15MarkdownASTNodeENS_9allocatorIS2_EEEE8™(A€ ä A  f\r0\r`\r\r\rÐ\r\rp\r\r€ Àà\r\r @ \r\r\r\rA UmŒA° !þ\n-Aà Á™ÅA 5¨]¸‹;OAÐ 5F¾\n&’îa=A MM J G D A > ¬¨Að `A€ •EA  ܘóAÀ \r”nAà ¼¨A€ \r’A  ±Ô$AÀ Eu,’Ø–«gYA  A  ”A° —  € @\n €/ _ 0A@Z€µÀ@րØ@ހ@.€2@6€9@G€J@v€xy@}€‚„†‡‰Š‹Ž‘“”–—˜œŸ @¤€¦§©¬®¯±²³µ·¸¼ÄÅÇÈÊË@Û€Þ@î€ñòôö÷ø@€ "@2€:;=>ACDEF@N€Eprv†ˆ@Š€ŒŽ‘@¡€£@«€ÂÏÐÑÕÖØ@î€ðñôõ÷ùúý@ÿ€@€@/€`@€€Š@¾€ÀÁ@Í€Ð@.€1@V€ @Å€ÇÍø@ý€€‚ƒ„…†‡ˆ‰@º€½@¿€@”€› @þ€@€@€(@/€8@?€H@M€Y[]_h@o€¸¹º»¾È@Ë€ØÙÚÛèéêëìøùúû&!*!+!2!`!@o!€ƒ!¶$@Ï$€,@/,€`,b,c,d,g,@k,€m,n,o,p,r,u,~,,€,@â,€ë,í,ò,@¦@l¦€€¦@š¦€"§@.§€2§@n§€y§{§}§~§@†§€‹§§§’§–§@¨§€ª§«§¬§­§®§°§±§²§³§´§@§€Ä§Å§Æ§Ç§É§Ë§Ì§@Ú§€Ü§Ý§â§õ§l«m«p«@¿«€!ÿ@:ÿ€@\'€°@Ó€p@z€|@Š€Œ@’€”•€ @² €P\r@e\r€ @¿€@n@_n€ n@¸n€@ßHßJßMßQßhß@n߀rß@~߀é@!é€az¼àöøþ/37:HKwÿz~sSƒ…TˆVWŒÝY[’`cih™oru¡¥€¨ƒ­ˆ°Š‹´¶’¹½ÆÆÉÉÌÌÜßïóóõ•¿ùž#3e,<šf,B€‰ŒGO¹qswó¬­¯ÌÍαÁÃËÃײ¸ÆÀÙïºÁ¸µøòû{}P_0Oa‹¿ÏÂÎÑ/a†-%-\'---ðõ24>ABBJcK¦ŠÐúýÿ•a¡ÿ \'07@EQSUW`g°±pq¹ruÐÑvwàáz{åxy|}ÉkåN!p!!„!Ð$é$0,_,a,k}}h,l,QqPRs,v,?@,ã,ì,î,ó,A¦m¦¦›¦#§/§3§o§z§|§y§‡§Œ§e‘§“§—§©§f\\aljž‡S«µ§Ã§”§‚Žȧʧdͧۧ›w|ö§K«L« ïAÿZÿ(OØû—¡£±³¹»¼À ò p\r…\rÀß`nn»nÓnAßIßKßNßRßißoßsßß"éCéAÐ2 Óß0Ið‡–—˜™šžP€@‡€ˆ@€@—€˜@Ÿ€ @§€¨@¯€²³´¶¼ÂÃÄÆÌÖäæòóôöüûûûûûûûûûû•ßA°4 ¥ssi¼nj e‚h1tw\ny\na¾ssʹ¹¹ ¹\'¹ ¹\'¹`¹g¹`¹g¹p¹±¹¬¹±B±¹t¹·¹®¹·B·¹¹BÁÅB|¹É¹Î¹ÉBɹfffiflststtvtetk~vtmssAà7 À°RTV·ÇÒÓ×âãç÷ûû¹ÅÅÅÅB±B¹·B¹¹¹¹BÅÅÅBÉB¹ffifflА.P05à  A´: ½!@/€:@@€[@`€{@~€¡@©€«@¬€®@±€´¶@¸€»¿×÷Â@Å€Ò@߀å@ë€íï@ÿ€u~„@…€‡ö‚Z@_€‰@Š€@€¾ÀÃÆó@ô€@€@€j@m€ÔÞéý@þ€@\r€ö@ù€þ@ÿ€0@>€^ˆd @e €p ò @ó €ú @û €ý v\nð\n@ñ\n€p ó @ú €w  „ O\ry\rô\r?OZ@[€@€@€468:@=€…¾@Å€Ç@Ì€Î@Ú€J@O€ž@Ÿ€û`@h€@™€m@n€›@œ€ë@í€5@6€Ô@Ö€Ø@Û€@\n€@D@E€Þ@ÿ€@€ @¦€¨@­€N@O€Z@j€t@€ü@ÿ€;@?€~@€À@Ç€Ó½¿@Á€Í@Ï€Ý@߀í@ï€ý@þ€ @\' €0 @^ €z @~ €Š @Ž €  @Ä €!@!€!@!€!@ !€!!@!€!@#!€%!\'!)!.!:!@;!€@!@D!€J!@M!€O!Š!@‹!€!@)$€@$@J$€œ$@é$€%@u\'€”\'@s+€v+@ÿ+€å,@ê,€ù,@ü,€þ,@ÿ,€p-.@..€0.@].€`.@c.€€.@™.€›.@ó.€/@Õ/€ð/@ÿ/€0@0€0@ 0€0060@70€=0@?0€›0@œ0€ 0û01@‘1€–1@Ÿ1€À1@å1€ï12@2€*2@G2€P2`2@2€Š2@°2€À2@ÿ3€ÀM@ÿM€¤@Ƥ€þ¤@ÿ¤€\r¦@¦€s¦~¦ò¦@÷¦€§@§€ §@!§€‰§@Ч€(¨@+¨€6¨@9¨€t¨@w¨€Î¨@Ϩ€ø¨@ú¨€ü¨.©@/©€_©Á©@Í©€Þ©@ß©€\\ª@_ª€wª@yª€Þª@ߪ€ðª@ñª€[«j«@k«€ë«)û²û@Òû€>ý@Oý€ý@‘ý€Èý@Ïý€üý@ÿý€þ@þ€0þ@Rþ€Tþ@fþ€hþ@kþ€ÿ@ÿ€ÿ@ ÿ€;ÿ@@ÿ€[ÿ@eÿ€àÿ@æÿ€èÿ@îÿ€üÿ@ýÿ€@€7@?€y@‰€Œ@Ž€@œ€ Ð@ü€ŸÐoWw@x€ ? P\n@X\n€\nÈ\nð\n@ö\n€9 @? €™ @œ €n\rŽ\r@\r€­É@Ê€Ð@Ø€U@Y€†@‰€G@M€»@¼€¾@Á€@@C€t@u€Å@È€ÍÛÝ@߀8@=€©Ô@Õ€×@Ø€K@O€Z@[€]ÆÁ@×€A@C€`@l€¹<@?€;D@F€â?@F€š@œ€ž@¢€@ €áA@E€p@q€÷@ø€C@O€Õ@ñ€ÿp$@t$€ñ/@ò/€nj@oj€õj7k@?k€Dk@Ek€mm@om€—n@šn€âoœ¼Ÿ¼Ì@ïÌ€úÌ@üÌ€Í@³Î€ºÎ@Ð΀ÒÎ@Ô΀ÝÎ@ý΀PÏ@ÃÏ€Ð@õЀÑ@&Ñ€)Ñ@dÑ€jÑ@lÑ€ƒÑ@„Ñ€ŒÑ@©Ñ€®Ñ@AÒ€EÒSÒ@ZÒ€]Ò@^Ò€`Ò@Ò€Ó@VÓ€ÁÖÛÖûÖ×5×O×o׉ש×Ãר@ÿÙ€7Ú@:Ú€mÚ@tÚ€vÚ@ƒÚ€…Ú@‹Ú€Û@Û€Oáÿâÿå^é@_逬ì°ì.íðî@ñî€ð@+ð€0ð@“ð€ ð@®ð€±ð@¿ð€Áð@Ïð€Ñð@õð€\rñ@®ñ€æñ@ò€ò@;ò€@ò@Hò€Pò@Qò€`ò@eò€ó@Ùö€Üö@ìö€ðö@üö€÷@Û÷€à÷@ë÷€ð÷@ ø€ø@Gø€Pø@Yø€`ø@‡ø€ø@­ø€°ø@»ø€Àø@Áø€Ðø@Øø€ù@Wú€`ú@mú€pú@|ú€€ú@Æú€ÈúÌú@Ýú€ßú@ëú€ïú@úú€û@’û€”û@ïû€úû A€Î A  \n\n\n   AÑÎ ! \r\r  A‹Ï  A—Ï  AÅÏ AÑÏ  AÿÏ A‹Ð  AÂÐ  AóÐ AÿÐ  A­Ñ A¹Ñ € 0123456789ABCDEF \r%)+/5;=CGIOSYaegkmqƒ‰‹•—£§­³µ¿ÁÅÇÓ \r%)+/5;=CGIOSYaegkmqyƒ‰‹•—£§©­³µ»¿ÁÅÇÑ ,h*NSt3__214__shared_countE¤,œ*`*NSt3__219__shared_weak_countEAÄÕ ø\ndè\' †@B€–˜áõʚ;00010203040506070809101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899H,Ä+(.N10__cxxabiv116__shim_type_infoEH,ô+¸+N10__cxxabiv117__class_type_infoEè+ !"#$%&h,\'!"#()*H,t,è+N10__cxxabiv120__si_class_type_infoEÄ,+!"#,-.H,Ð,è+N10__cxxabiv121__vmi_class_type_infoEL-/0h-124-34 ,<-St9exceptionH,X-4-St9bad_allocH,t-L-St20bad_array_new_length¤-56H,°-4-St11logic_errorÔ-76H,à-¤-St12length_error.86H,.¤-St12out_of_range ,0.St9type_infoAÁÜ  1€'); ++ return base64Decode("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8AFrIgMkAAJAAkAgAkUEQEEBIQkMAQsCQAJAAkACQAJAAkACQAJAAkACQAJAAkACQCAADhACAQAGBA0FBwgNAwkKCw0MDQtBPBB/IgBCADcCECAAQQM2AgwgAEGUFzYCACAAQgA3AgQgAEIANwI0IABCgICA/AM3AiwgAEIANwIYIABCADcCICAAQQA2AiggAEEMaiEGAkAgAUUNAAJAAkAgASgCBCIEBEAgASgCACIHDQELIANBADYC6AEgA0IANwPgAQwBCyAEQfj///8HTw0PAkAgBEELTwRAIARBB3IiCEEBahB/IQUgAyAIQf////8HazYC6AEgAyAFNgLgASADIAQ2AuQBDAELIAMgBDoA6wEgA0HgAWohBQsgBARAIAUgByAE/AoAAAsgBCAFakEAOgAAIAMoAuQBIAMtAOsBIgQgBMBBAEgbRQ0AIAZBkNwAIANB4AFqEBoLAkACQCABKAIUIgQEQCABKAIQIgUNAQsgA0EANgLYASADQgA3A9ABDAELIARB+P///wdPDQ8CQCAEQQtPBEAgBEEHciIHQQFqEH8hASADIAdB/////wdrNgLYASADIAE2AtABIAMgBDYC1AEMAQsgAyAEOgDbASADQdABaiEBCyAEBEAgASAFIAT8CgAACyABIARqQQA6AAAgAygC1AEgAy0A2wEiASABwEEASBtFDQAgBkGc3AAgA0HQAWoQGgsgAywA2wFBAEgEQCADKALYARogAygC0AEQcgsgAywA6wFBAE4NACADKALoARogAygC4AEQcgsgAyAANgLMASADIAY2AsgBIAAgACgCBEEBajYCBCADIAMpAsgBNwMAIAIgAxAYIAAgACgCBCICQQFrNgIEIAINDCAAIAAoAgAoAggRAQAgABB8DAwLQTwQfyIAQgA3AhAgAEEGNgIMIABBlBc2AgAgAEIANwIEIABCADcCNCAAQoCAgPwDNwIsIABCADcCGCAAQgA3AiAgAEEANgIoIAMgADYCxAEgAyAAQQxqNgLAASADIAMpAsABNwMIIAIgA0EIahAYDAsLQTwQfyIAQgA3AhAgAEEHNgIMIABBlBc2AgAgAEIANwIEIABCADcCNCAAQoCAgPwDNwIsIABCADcCGCAAQgA3AiAgAEEANgIoIAMgADYCvAEgAyAAQQxqNgK4ASADIAMpArgBNwMQIAIgA0EQahAYDAoLQTwQfyIAQgA3AhAgAEEJNgIMIABBlBc2AgAgAEIANwIEIABCADcCNCAAQoCAgPwDNwIsIABCADcCGCAAQgA3AiAgAEEANgIoIAMgADYCtAEgAyAAQQxqNgKwASADIAMpArABNwMYIAIgA0EYahAYDAkLQTwQfyIAQgA3AhAgAEEKNgIMIABBlBc2AgAgAEIANwIEIABCADcCNCAAQoCAgPwDNwIsIABCADcCGCAAQgA3AiAgAEEANgIoIAMgADYCrAEgAyAAQQxqNgKoASADIAMpAqgBNwMgIAIgA0EgahAYDAgLQTwQfyIAQgA3AhAgAEEINgIMIABBlBc2AgAgAEIANwIEIABCADcCNCAAQoCAgPwDNwIsIABCADcCGCAAQgA3AiAgAEEANgIoIAMgADYCpAEgAyAAQQxqNgKgASADIAMpAqABNwMoIAIgA0EoahAYDAcLQTwQfyIAQgA3AhAgAEELNgIMIABBlBc2AgAgAEIANwIEIABCADcCNCAAQoCAgPwDNwIsIABCADcCGCAAQgA3AiAgAEEANgIoIABBDGohBgJAIAFFDQACQAJAIAEoAgQiBARAIAEoAgAiBw0BCyADQQA2AugBIANCADcD4AEMAQsgBEH4////B08NCQJAIARBC08EQCAEQQdyIghBAWoQfyEFIAMgCEH/////B2s2AugBIAMgBTYC4AEgAyAENgLkAQwBCyADIAQ6AOsBIANB4AFqIQULIAQEQCAFIAcgBPwKAAALIAQgBWpBADoAACADKALkASADLQDrASIEIATAQQBIG0UNACAGQZDcACADQeABahAaCwJAAkAgASgCFCIEBEAgASgCECIFDQELIANBADYC2AEgA0IANwPQAQwBCyAEQfj///8HTw0JAkAgBEELTwRAIARBB3IiB0EBahB/IQEgAyAHQf////8HazYC2AEgAyABNgLQASADIAQ2AtQBDAELIAMgBDoA2wEgA0HQAWohAQsgBARAIAEgBSAE/AoAAAsgASAEakEAOgAAIAMoAtQBIAMtANsBIgEgAcBBAEgbRQ0AIAZBnNwAIANB0AFqEBoLIAMsANsBQQBIBEAgAygC2AEaIAMoAtABEHILIAMsAOsBQQBODQAgAygC6AEaIAMoAuABEHILIAMgADYCnAEgAyAGNgKYASAAIAAoAgRBAWo2AgQgAyADKQKYATcDMCACIANBMGoQGCAAIAAoAgQiAkEBazYCBCACDQYgACAAKAIAKAIIEQEAIAAQfAwGC0E8EH8iAEIANwIQIABBGDYCDCAAQZQXNgIAIABCADcCBCAAQgA3AjQgAEKAgID8AzcCLCAAQgA3AhggAEIANwIgIABBADYCKCADIAA2ApQBIAMgAEEMajYCkAEgAyADKQKQATcDOCACIANBOGoQGAwFC0E8EH8iAEIANwIQIABBGTYCDCAAQZQXNgIAIABCADcCBCAAQgA3AjQgAEKAgID8AzcCLCAAQgA3AhggAEIANwIgIABBADYCKCADIAA2AowBIAMgAEEMajYCiAEgAyADKQKIATcDQCACIANBQGsQGAwEC0E8EH8iAEIANwIQIABBGjYCDCAAQZQXNgIAIABCADcCBCAAQgA3AjQgAEKAgID8AzcCLCAAQgA3AhggAEIANwIgIABBADYCKCADIAA2AoQBIAMgAEEMajYCgAEgAyADKQKAATcDSCACIANByABqEBgMAwtBPBB/IgBCADcCECAAQRs2AgwgAEGUFzYCACAAQgA3AgQgAEIANwI0IABCgICA/AM3AiwgAEIANwIYIABCADcCICAAQQA2AiggAyAANgJ8IAMgAEEMajYCeCADIAMpAng3A1AgAiADQdAAahAYDAILQTwQfyIAQgA3AhAgAEEcNgIMIABBlBc2AgAgAEIANwIEIABCADcCNCAAQoCAgPwDNwIsIABCADcCGCAAQgA3AiAgAEEANgIoIAMgADYCdCADIABBDGo2AnAgAyADKQJwNwNYIAIgA0HYAGoQGAwBC0E8EH8iAEIANwIQIABBHTYCDCAAQZQXNgIAIABCADcCBCAAQgA3AjQgAEKAgID8AzcCLCAAQgA3AhggAEIANwIgIABBADYCKCADIAA2AmwgAyAAQQxqNgJoIAMgAykCaDcDYCACIANB4ABqEBgLIANB8AFqJAAgCQ8LEAcAC9cYAQp/IwBB4ABrIgMkAAJAIAJFBEBBASEADAELAkACQCAADgkCAQEBAQEBAQABC0EAIQAgAkEAOgAkIANCADcDGCADQgA3AxAgA0KAgICAgICAwD83AyAgA0IANwMIAkAgAigCLCACLAAzIgQgBEEASCIBGyIFRQ0AIAJBKGoiBigCACIHIAYgARshAQNAIAAgAWotAAAQUwRAIABBAWoiACAFRw0BDAILCyAHIAYgBEEASBsgAGotAABBPEcNAAJAIABBAWoiACAFTw0AIAcgBiAEQQBIGyIBIABqLQAAQS9GDQEDQCAAIAFqLQAAEFNFDQEgAEEBaiIAIAVHDQALDAELIAAgBU8NACAHIAYgBEEASBshByAAIQECQANAIAEgB2oiBC0AABBTDQEgBC0AAEE+Rg0BIAQtAABBL0YNASABQQFqIgEgBUcNAAsgBSEBCyAAIAFGDQAgA0EIaiABIABrEJgBIAAgAUkEQANAIANBCGogAigCKCAGIAIsADNBAEgbIABqLQAAEGLAEJ0BIABBAWoiACABRw0ACwsgASACKAIsIgggAiwAMyIJIAlBAEgbIgBPDQAgCUEfdiEFIANBFGohCiADQdAAaiELA0AgBigCACAGIAVBAXEbIQUDQCABIAVqIgQtAAAQUwRAIAFBAWoiASAASQ0BDAMLCyAELQAAQT5GDQEgBC0AAEEvRg0BAkACQCAAIAFLBEAgASEEAkADQCAEIAVqIgctAABBPUYNASAHLQAAEFMNASAHLQAAQT5GDQEgBy0AAEEvRg0BIARBAWoiBCAASQ0ACyAAIQQLIAEgBEcNAQsgAUEBaiEBDAELIAtBADYCACADQgA3A0ggA0HIAGogBCABaxCYASABIARJBEADQCADQcgAaiACKAIoIAYgAiwAM0EASBsgAWotAAAQYsAQnQEgAUEBaiIBIARJDQALCwJAAn8CQCAEIAIoAiwgAiwAMyIAIABBAEgiBRsiAE8NACAGKAIAIAYgBRshBQJAA0AgBCAFaiIBLQAAEFNFDQEgBEEBaiIEIABHDQALIAAMAgsgAS0AAEE9Rw0AAkACQAJAAkACQANAIAAgBCIHQQFqIgRNDQEgBCAFaiIBLQAAEFMNAAsgA0FAayIJQQA2AgAgA0IANwM4AkAgAS0AAEEiRg0AIAEtAABBJ0YNACAEIQEDQCABIAVqIgktAAAQUw0DIAktAABBPkYNAyAJLQAAQS9GDQMgAUEBaiIBIABHDQALIAAhAQwCCyAHQQJqIgchBAJAIAAgB00NACABLQAAIQEDQCAEIAVqLQAAIAFGDQEgBEEBaiIEIABJDQALIAAhBAsgACAHayIAIAQgB2siASAAIAFJGyIAQfj///8HTw0DAkACQCAAQQtPBEAgAEEHciIIQQFqEH8hASADIAhB/////wdrNgI0IAMgATYCLCADIAA2AjAMAQsgAyAAOgA3IANBLGohASAARQ0BCyAARQ0AIAEgBSAHaiAA/AoAAAsgACABakEAOgAAIAMsAENBAEgEQCADKAJAGiADKAI4EHILIAkgAygCNDYCACADIAMpAiw3AzggBCAEIAIoAiwgAiwAMyIAIABBAEgbSWohAQwCCyADQUBrQQA2AgAgA0IANwM4IAQhAQsgACAHTQ0CIAAgBGsiACABIARrIgcgACAHSRsiAEH4////B08NAQJAAkAgAEELTwRAIABBB3IiCUEBahB/IQcgAyAJQf////8HazYCNCADIAc2AiwgAyAANgIwDAELIAMgADoANyADQSxqIQcgAEUNAQsgAEUNACAHIAQgBWogAPwKAAALIAAgB2pBADoAACADLABDQQBIBEAgAygCQBogAygCOBByCyADQUBrIAMoAjQ2AgAgAyADKQIsNwM4CyADIANByABqNgJcIANBLGogCiADQcgAaiADQdwAahAZAkAgAygCLCIFQRRqIgAgA0E4akYNACADLABDIQQgBSwAH0EATgRAIARBAE4EQCAAIAMpAzg3AgAgACADQUBrKAIANgIIDAcLIAAgAygCOCADKAI8EJwBDAELIAAgAygCOCADQThqIARBAEgiBRsgAygCPCAEIAUbEJsBCyADLABDQQBODQQgAygCQBogAygCOBByDAQLEAcAC0EIEKgBQfIOEIEBIgBBrNsANgIAIABBuNsAQQEQAAALIAQLIQEgAyADQcgAajYCLCADQThqIAogA0HIAGogA0EsahAZAn8gAygCOCIALAAfQQBIBEAgAEEANgIYIAAoAhQMAQsgAEEAOgAfIABBFGoLQQA6AAALIAMsAFNBAEgEQCADKAJQGiADKAJIEHILIAIoAiwhCCACLQAzIQkLIAEgCCAJQf8BcSAJwEEASCIFGyIASQ0ACwtBACEAQQAhBQJAIAMoAgwgAywAEyIBIAFBAEgbQQVHDQAgAygCCCADQQhqIAFBAEgbQcAMQQUQVQ0AIANBAzoAUyADQQA6AEsgA0HnEC8AADsBSCADQekQLQAAOgBKAn8gA0EUaiEKQQAhCSADQcgAaiIGKAIEIAYsAAsiCCAIQQBIIgQbIgchCCAGKAIAIAYgBBsi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+AEgA0H4AWogBUEASCIEGyADKAL8ASAFIAQbEJsBCyADLACDAkEATg0AIAMoAoACGiADKAL4ARByCyADIAA2AvQBIAMgAEEMajYC8AEgACAAKAIEQQFqNgIEIAMgAykC8AE3AwggAiADQQhqEBggACAAKAIEIgJBAWs2AgQgAg0OIAAgACgCACgCCBEBACAAEHwMDgtBPBB/IgBCADcCECAAQQw2AgwgAEGUFzYCACAAQgA3AgQgAEIANwI0IABCgICA/AM3AiwgAEIANwIYIABCADcCICAAQQA2AiggAyAANgLsASADIABBDGo2AugBIAMgAykC6AE3AxAgAiADQRBqEBgMDQtBPBB/IgBCADcCECAAQSA2AgwgAEGUFzYCACAAQgA3AgQgAEIANwI0IABCgICA/AM3AiwgAEIANwIYIABCADcCICAAQQA2AiggAEEMaiEEAkAgAUUNAAJAAkAgASgCBCIFBEAgASgCACIGDQELIANBADYCgAIgA0IANwP4AQwBCyAFQfj///8HTw0PAkAgBUELTwRAIAVBB3IiB0EBahB/IQEgAyAHQf////8HazYCgAIgAyABNgL4ASADIAU2AvwBDAELIAMgBToAgwIgA0H4AWohAQsgBQRAIAEgBiAF/AoAAAsgASAFakEAOgAAIAMoAvwBIAMtAIMCIgEgAcBBAEgbRQ0AIARB9NwAIANB+AFqEBoLIAMsAIMCQQBODQAgAygCgAIaIAMoAvgBEHILIAMgADYC5AEgAyAENgLgASAAIAAoAgRBAWo2AgQgAyADKQLgATcDGCACIANBGGoQGCAAIAAoAgQiAkEBazYCBCACDQwgACAAKAIAKAIIEQEAIAAQfAwMC0E8EH8iAEIANwIQIABBDTYCDCAAQZQXNgIAIABCADcCBCAAQgA3AjQgAEKAgID8AzcCLCAAQgA3AhggAEIANwIgIABBADYCKCADIAA2AtwBIAMgAEEMajYC2AEgAyADKQLYATcDICACIANBIGoQGAwLC0E8EH8iAEIANwIQIABBDjYCDCAAQZQXNgIAIABCADcCBCAAQgA3AjQgAEKAgID8AzcCLCAAQgA3AhggAEIANwIgIABBADYCKCAAQQxqIQQCQCABRQ0AIAEoAgAiAUEBRg0AIANB+AFqIAEQnwEgBEHc3AAgA0H4AWoQGiADLACDAkEATg0AIAMoAoACGiADKAL4ARByCyADIAA2AtQBIAMgBDYC0AEgACAAKAIEQQFqNgIEIAMgAykC0AE3AyggAiADQShqEBggACAAKAIEIgJBAWs2AgQgAg0KIAAgACgCACgCCBEBACAAEHwMCgtBPBB/IgBCADcCECAAQQ82AgwgAEGUFzYCACAAQgA3AgQgAEIANwI0IABCgICA/AM3AiwgAEIANwIYIABCADcCICAAQQA2AiggAEEMaiEEAkAgAUUNACABKAIARQ0AIARBxNwAIANB+AFqQacPEBsiBRAaIAUsAAtBAEgEQCAFKAIIGiAFKAIAEHILIARB0NwAIANB+AFqQacPQccPIAEtAARB3wFxQdgARhsQGyIBEBogASwAC0EATg0AIAEoAggaIAEoAgAQcgsgAyAANgLMASADIAQ2AsgBIAAgACgCBEEBajYCBCADIAMpAsgBNwMwIAIgA0EwahAYIAAgACgCBCICQQFrNgIEIAINCSAAIAAoAgAoAggRAQAgABB8DAkLQTwQfyIAQgA3AhAgAEEQNgIMIABBlBc2AgAgAEIANwIEIABCADcCNCAAQoCAgPwDNwIsIABCADcCGCAAQgA3AiAgAEEANgIoIABBDGohBAJAIAFFDQACQCABLQAgIgVFDQAgA0EAOgClASADIAU6AKQBIARBqNwAIANB+AFqIANBpAFqEBsiBRAaIAUsAAtBAE4NACAFKAIIGiAFKAIAEHILAkACQCABKAIUIgUEQCABKAIQIgYNAQsgA0EANgKAAiADQgA3A/gBDAELIAVB+P///wdPDQsCQCAFQQtPBEAgBUEHciIHQQFqEH8hASADIAdB/////wdrNgKAAiADIAE2AvgBIAMgBTYC/AEMAQsgAyAFOgCDAiADQfgBaiEBCyAFBEAgASAGIAX8CgAACyABIAVqQQA6AAAgAygC/AEgAy0AgwIiASABwEEASBtFDQAgBEG43AAgA0H4AWoQGgsgAywAgwJBAE4NACADKAKAAhogAygC+AEQcgsgAyAANgLEASADIAQ2AsABIAAgACgCBEEBajYCBCADIAMpAsABNwM4IAIgA0E4ahAYIAAgACgCBCICQQFrNgIEIAINCCAAIAAoAgAoAggRAQAgABB8DAgLQTwQfyIAQgA3AhAgAEERNgIMIABBlBc2AgAgAEIANwIEIABCADcCNCAAQoCAgPwDNwIsIABCADcCGCAAQgA3AiAgAEEANgIoIAMgADYCvAEgAyAAQQxqNgK4ASADIAMpArgBNwNAIAIgA0FAaxAYDAcLQTwQfyIAQgA3AhAgAEEfNgIMIABBlBc2AgAgAEIANwIEIABCADcCNCAAQoCAgPwDNwIsIABCADcCGCAAQgA3AiAgAEEANgIoIABBDGohBAJAIAFFDQAgA0H4AWogASgCABCfASADQejcADYCmAIgA0GkAWogAEEcakHo3AAgA0GYAmoQGQJAIAMoAqQBIgVBFGoiASADQfgBakYNACADLACDAiEGIAUsAB9BAE4EQCAGQQBOBEAgASADKQL4ATcCACABIAMoAoACNgIIDAILIAEgAygC+AEgAygC/AEQnAEMAQsgASADKAL4ASADQfgBaiAGQQBIIgUbIAMoAvwBIAYgBRsQmwELIAMsAIMCQQBODQAgAygCgAIaIAMoAvgBEHILIAMgADYCtAEgAyAENgKwASAAIAAoAgRBAWo2AgQgAyADKQKwATcDSCACIANByABqEBggACAAKAIEIgJBAWs2AgQgAg0GIAAgACgCACgCCBEBACAAEHwMBgtBPBB/IgBCADcCECAAQRI2AgwgAEGUFzYCACAAQgA3AgQgAEIANwI0IABCgICA/AM3AiwgAEIANwIYIABCADcCICAAQQA2AiggAEEMaiEFAkAgAUUNACADQQA6AIACIANC496xm/Stnbf0ADcD+AEgA0EIOgCDAiADQaQBaiABKAIAEJ8BIAMgA0H4AWo2ApQCIANBmAJqIABBHGoiBiADQfgBaiADQZQCahAZAkAgAygCmAIiB0EUaiIEIANBpAFqRg0AIAMsAK8BIQggBywAH0EATgRAIAhBAE4EQCAEIAMpAqQBNwIAIAQgAygCrAE2AggMAgsgBCADKAKkASADKAKoARCcAQwBCyAEIAMoAqQBIANBpAFqIAhBAEgiBxsgAygCqAEgCCAHGxCbAQsgAywArwFBAEgEQCADKAKsARogAygCpAEQcgsgAywAgwJBAEgEQCADKAKAAhogAygC+AEQcgsgA0EQEH8iBDYC+AEgA0KMgICAgIKAgIB/NwL8ASAEQf0JKAAANgAIIARB9QkpAAA3AAAgBEEAOgAMIANBpAFqIAEoAgQQnwEgAyADQfgBajYClAIgA0GYAmogBiADQfgBaiADQZQCahAZAkAgAygCmAIiB0EUaiIEIANBpAFqRg0AIAMsAK8BIQggBywAH0EATgRAIAhBAE4EQCAEIAMpAqQBNwIAIAQgAygCrAE2AggMAgsgBCADKAKkASADKAKoARCcAQwBCyAEIAMoAqQBIANBpAFqIAhBAEgiBxsgAygCqAEgCCAHGxCbAQsgAywArwFBAEgEQCADKAKsARogAygCpAEQcgsgAywAgwJBAEgEQCADKAKAAhogAygC+AEQcgsgA0EQEH8iBDYC+AEgA0KMgICAgIKAgIB/NwL8ASAEQfAJKAAANgAIIARB6AkpAAA3AAAgBEEAOgAMIANBpAFqIAEoAggQnwEgAyADQfgBajYClAIgA0GYAmogBiADQfgBaiADQZQCahAZAkAgAygCmAIiBEEUaiIBIANBpAFqRg0AIAMsAK8BIQYgBCwAH0EATgRAIAZBAE4EQCABIAMpAqQBNwIAIAEgAygCrAE2AggMAgsgASADKAKkASADKAKoARCcAQwBCyABIAMoAqQBIANBpAFqIAZBAEgiBBsgAygCqAEgBiAEGxCbAQsgAywArwFBAEgEQCADKAKsARogAygCpAEQcgsgAywAgwJBAE4NACADKAKAAhogAygC+AEQcgsgAyAANgKgASADIAU2ApwBIAAgACgCBEEBajYCBCADIAMpApwBNwNQIAIgA0HQAGoQGCAAIAAoAgQiAkEBazYCBCACDQUgACAAKAIAKAIIEQEAIAAQfAwFC0E8EH8iAEIANwIQIABBEzYCDCAAQZQXNgIAIABCADcCBCAAQgA3AjQgAEKAgID8AzcCLCAAQgA3AhggAEIANwIgIABBADYCKCADIAA2ApgBIAMgAEEMajYClAEgAyADKQKUATcDWCACIANB2ABqEBgMBAtBPBB/IgBCADcCECAAQRQ2AgwgAEGUFzYCACAAQgA3AgQgAEIANwI0IABCgICA/AM3AiwgAEIANwIYIABCADcCICAAQQA2AiggAyAANgKQASADIABBDGo2AowBIAMgAykCjAE3A2AgAiADQeAAahAYDAMLQTwQfyIAQgA3AhAgAEEVNgIMIABBlBc2AgAgAEIANwIEIABCADcCNCAAQoCAgPwDNwIsIABCADcCGCAAQgA3AiAgAEEANgIoIAMgADYCiAEgAyAA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IQwDQCAGIApBA3QiDWooAgAiASgCACIJQQ1rQQJPBH8gCkEBagVBASEIAkAgASgCJCIFIAEoAigiBEYNACAFIQEDQAJAAkAgASgCACICKAIAQQ9HDQAgAigCKCACKAIkIgJrQQhHDQAgAigCACgCAEEhRg0BCyABQQhqIgEgBEcNAQwCCwsgA0EANgIcIANCADcCFCADQQA2AhAgA0IANwIIA0ACQAJAIAUoAgAiASgCAEEPRw0AIAEoAiggASgCJCIBa0EIRw0AIAEoAgAoAgBBIUcNACADKAIIIgIgAygCDCIGRwRAQTwQfyIBQgA3AhAgASAJNgIMIAFBlBc2AgAgAUIANwIEIAFCADcCGCABQgA3AiAgAUKAgICAgICAwD83AiggAyABNgIEIAMgAUEMajYCACABIANBEGoiBygCADYCOCABIAY2AjQgASACNgIwIAdBADYCACADQgA3AwggA0EUaiADEB0CQCADKAIEIgFFDQAgASABKAIEIgJBAWs2AgQgAg0AIAEgASgCACgCCBEBACABEHwLIAUoAgAoAiQhAQsgAygCGCICIAMoAhwiB0kEQCACIAEoAgA2AgAgAiABKAIEIgE2AgQgAQRAIAEgASgCBEEBajYCBAsgAyACQQhqNgIYDAILIAIgAygCFCIGayICQQN1Ig5BAWoiCEGAgICAAk8NB0H/////ASAHIAZrIgdBAnUiCyAIIAggC0kbIAdB+P///wdPGyIIQYCAgIACTw0IIAhBA3QiBxB/IgsgAmoiCCABKAIANgIAIAggASgCBCIBNgIEIAcgC2ohByAIIAEEfyABIAEoAgRBAWo2AgQgAygCHBogAygCGCAGayICQQN1BSAOC0EDdGshASACBEAgASAGIAL8CgAACyADIAc2AhwgAyAIQQhqIgI2AhggAyABNgIUIAYEQCAGEHILIAMgAjYCGAwBCyADQQhqIAUQHQsgBUEIaiIFIARHDQALAkAgAygCCCICIAMoAgwiBEYNAEE8EH8iAUIANwIQIAEgCTYCDCABQZQXNgIAIAFCADcCBCABQgA3AhggAUIANwIgIAFCgICAgICAgMA/NwIoIAMgATYCBCADIAFBDGo2AgAgASADKAIQNgI4IAEgBDYCNCABIAI2AjAgA0EANgIQIANCADcDCCADQRRqIAMQHSADKAIEIgFFDQAg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ASwAH0EASARAIAEoAhwaIAEoAhQQcgsgASwAE0EASARAIAEoAhAaIAEoAggQcgsgARByIAIiAQ0ACwsgACgCACEBIABBADYCACABBEAgACgCBBogARByCwuNAgEGfyAAKAIEIgIgACgCCCIDSQRAIAIgASgCADYCACACIAEoAgQ2AgQgAUIANwIAIAAgAkEIajYCBA8LAkAgAiAAKAIAIgRrIgVBA3UiB0EBaiICQYCAgIACSQRAQf////8BIAMgBGsiBkECdSIDIAIgAiADSRsgBkH4////B08bIgMEfyADQYCAgIACTw0CIANBA3QQfwVBAAsiBiAFaiICIAEoAgA2AgAgAiABKAIENgIEIAFCADcCACACIAdBA3RrIQEgBQRAIAEgBCAF/AoAAAsgACAGIANBA3RqNgIIIAAgAkEIaiICNgIEIAAgATYCACAEBEAgBBByCyAAIAI2AgQPCxATAAsQFAALzgEBA38jAEEQayICJAAgABAQAkAgASgCACIDRQ0AIAAoAgggACgCDCIARg0AIABBCGsoAgAhBCABKAIEIgAEQCAAIAAoAgRBAWo2AgQLIAIgADYCDCACIAM2AgggBEEkaiACQQhqEB0gAigCDCIARQ0AIAAgACgCBCIDQQFrNgIEIAMNACAAIAAoAgAoAggRAQAgABB8CwJAIAEoAgQiAUUNACABIAEoAgQiAEEBazYCBCAADQAgASABKAIAKAIIEQEAIAEQfAsgAkEQaiQAC90FAQd/IwBBMGsiASQAIAAoAgAiAygCACIEIAMoAgQiAkcEQCAEIQMCQAJAA0AgAygCABARBEAgAiADQQhqIgNHDQEMAgsLQTwQfyICQgA3AhAgAkEBNgIMIAJBlBc2AgAgAkIANwIEIAJCADcCNCACQoCAgPwDNwIsIAJCADcCGCACQgA3AiAgAkEANgIoIAEgAjYCHCABIAJBDGo2AhggAUGqCi0AADoAECABQQU6ABcgAUGmCigAADYCDCABQQA6ABEgAUEAOgAEIAFB9OTVqwY2AgAgAUEEOgALIAEgAUEMajYCJCABQShqIAJBHGogAUEMaiABQSRqEBkCQCABKAIoIgNBFGoiBCABRg0AIAMsAB9BAE4EQCAEIAEpAgA3AgAgBCABKAIINgIIDAELIAQgAUEEEJsBIAEsAAtBAE4NACABKAIIGiABKAIAEHILIAEsABdBAEgEQCABKAIUGiABKAIMEHILIAAoAgAhBSACKAIwIgcEQCAHIgMgAigCNCIERwRAA0ACQCAEQQRrKAIAIgNFDQAgAyADKAIEIgZBAWs2AgQgBg0AIAMgAygCACgCCBEBACADEHwLIAcgBEEIayIERw0ACyACKAIwIQMLIAIgBzYCNCACKAI4GiADEHIgAkEANgI4IAJCADcCMAsgAiAFKAIANgIwIAIgBSgCBDYCNCACIAUoAgg2AjggBUEANgIIIAVCADcCACAAKAIEIAFBGGoQHSABKAIcIgRFDQEgBCAEKAIEIgNBAWs2AgQgAw0BIAQgBCgCACgCCBEBACAEEHwMAQsDQCAAKAIEIAQQHSAEQQhqIgQgAkcNAAsLIAAoAgAiBigCACIAIAYoAgQiBEcEQANAAkAgBEEEaygCACIDRQ0AIAMgAygCBCICQQFrNgIEIAINACADIAMoAgAoAggRAQAgAxB8CyAAIARBCGsiBEcNAAsLIAYgADYCBAsgAUEwaiQACyAAQY/cACwAAEEASARAQYzcACgCABpBhNwAKAIAEHILCyAAQZvcACwAAEEASARAQZjcACgCABpBkNwAKAIAEHILCyAAQafcACwAAEEASARAQaTcACgCABpBnNwAKAIAEHILCyAAQbPcACwAAEEASARAQbDcACgCABpBqNwAKAIAEHILCyAAQcPcACwAAEEASARAQcDcACgCABpBuNwAKAIAEHILCyAAQc/cACwAAEEASARAQczcACgCABpBxNwAKAIAEHILCyAAQdvcACwAAEEASARAQdjcACgCABpB0NwAKAIAEHILCyAAQefcACwAAEEASARAQeTcACgCABpB3NwAKAIAEHILCyAAQfPcACwAAEEASARAQfDcACgCABpB6NwAKAIAEHILCyAAQf/cACwAAEEASARAQfzcACgCABpB9NwAKAIAEHILCwwAIABBlBc2AgAgAAsOACAAQZQXNgIAIAAQcgusAQEFfyMAQRBrIgQkACAAQQxqIgEoAiQiAgRAIAIiACABKAIoIgNHBEADQAJAIANBBGsoAgAiAEUNACAAIAAoAgQiBUEBazYCBCAFDQAgACAAKAIAKAIIEQEAIAAQfAsgAiADQQhrIgNHDQALIAEoAiQhAAsgASACNgIoIAEoAiwaIAAQcgsgAUEQ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ACABGyEADAELCyADQRBqJAAgBUEQaiQAIAALBQAQdgALDQAgACgCACABKAIASQsEACAACyoBAX8CQCAAQQhqIgEoAgAEQCABEH1Bf0cNAQsgACAAKAIAKAIQEQEACwsTACAAIAAoAgBBAWsiADYCACAACwQAQQALPQECf0EBIAAgAEEBTRshAQNAAkAgARBxIgINAEGw4gAoAgAiAEUNACAAEQkADAELCyACIgBFBEAQeQsgAAsNACAAQdjZADYCACAAC10BA38gABCAASIAQcjaADYCACAAQQRqIQQgARBhIgNBDWoQfyICQQA2AgggAiADNgIEIAIgAzYCACACQQxqIQIgA0EBaiIDBEAgAiABIAP8CgAACyAEIAI2AgAgAAsKACAALQALQQd2CxUAIAAQggEEQCAAKAIEDwsgABCHAQsbAQF/QQohASAAEIIBBH8gABCIAUEBawUgAQsLEgAgABCCAQRAIAAoAgAPCyAAC6gCAQN/IwBBIGsiCCQAQff///8HIgkgAUF/c2ogAk8EQCAAEIUBIQogAUHz////A0kEQCAIIAFBAXQ2AhwgCCABIAJqNgIQIAhBEGogCEEcahCMASgCABCNAUEBaiEJCyAIQRxqIAhBGGogABCOASgCABCPASAIQRBqIAkQkAEgCCgCECEJIAgoAhQaIAQEQCAJIAogBBCRAQsgBgRAIAQgCWogByAGEJEBCyADIAQgBWoiB2shAiADIAdHBEAgBCAJaiAGaiAEIApqIAVqIAIQkQELIAFBCkcEQCAKEHILIAAgCRCSASAAIAgoAhQQkwEgACAEIAZqIAJqIgQQlAEgCEEAOgAPIAQgCWogCEEPahCLASAIQRxqEJoBIAhBIGokAA8LEJUBAAsLACAALQALQf8AcQsOACAAKAIIQf////8HcQsZAAJAIAJFDQAgAkUNACAAIAEgAvwKAAALCxkAIAAQggEEQCAAIAEQlAEPCyAAIAEQlwELDAAgACABLQAAOgAACyMBAn8jAEEQayICJAAgACABEHohAyACQRBqJAAgASAAIAMbCyQAIABBC08EfyAAQQhqQXhxIgAgAEEBayIAIABBC0YbBUEKCwsLACAAIAE2AgAgAAsKACAAIAEQjgEaCxgBAX8gARB/IQIgACABNgIEIAAgAjYCAAsLACAAIAEgAhCJAQsJACAAIAE2AgALEAAgACABQYCAgIB4cjYCCAsJACAAIAE2AgQLBQAQeQALBwAgAEELSQsNACAAIAFB/wBxOgALC64CAQZ/IAFB9////wdNBEAgABCEASABSQRAIAEQjQEhAiMAQRBrIgEkACABQQxqIAFBCGogABCOASgCABCPASAAEIQBIQQgABCDASEGAkACfyACEJYBIgcEQEEBIQQgAkEBaiEFIAAhAiAAKAIADAELIAJBAWohAwJAIAIgBEsEQCABIAMQkAEgASgCBCEFIAEoAgAhAgwBCyABIAMQkAEgASgCBCEDIAAQhAEhBCABKAIEIQUgASgCACECIANBAWsgBE0NACACEHIMAgsgABCCASEEIAAQhQELIQMgAiADIAAQgwFBAWoQkQEgBARAIAMQcgsgB0UEQCAAIAUQkwEgACAGEJQBIAAgAhCSAQwBCyAAIAYQlwELIAFBDGoQmgEgAUEQaiQACw8LEJUBAAt9AQN/IwBBEGsiBSQAAkAgAiAAEIQBIgQgABCDASIDa00EQCACRQ0BIAAQhQEiBCADaiABIAIQkQEgACACIANqIgIQigEgBUEAOgAPIAIgBGogBUEPahCLAQwBCyAAIAQgAiAEayADaiADIANBACACIAEQhgELIAVBEGokAAsLACAAKAIAEIMBGgt2AQN/IwBBEGsiBCQAIAAQiAEhAyAAKAIEIQUCQCACIANJBEAgACgCACEDIAAgAhCUASADIAEgAhCRASAEQQA6AA8gAiADaiAEQQ9qEIsBDAELIAAgA0EBayACIANrQQFqIAVBACAFIAIgARCGAQsgBEEQaiQAC2IBAn8jAEEQayIDJAAgABCHASEEAkAgAkEKTQRAIAAgAhCXASAAIAEgAhCRASADQQA6AA8gACACaiADQQ9qEIsBDAELIABBCiACQQprIARBACAEIAIgARCGAQsgA0EQaiQAC4IDAQZ/IwBBEGsiBCQAIAQgAToADwJAAkACfyAAEIIBIgNFBEBBCiECIAAQhwEMAQsgABCIAUEBayECIAAoAgQLIgEgAkYEQCMAQRBrIgUkACAFQQxqIAVBCGogABCOASgCABCPASMAQRBrIgMkAAJAIAJB9////wdHBEAgABCFASEGIANBBGogAkHz////A0kEfyADIAJBAXQ2AgwgAyACQQFqNgIEIANBBGogA0EMahCMASgCABCNAUEBagVB9////wcLEJABIAMoAgQhByADKAIIGiACBEAgByAGIAIQkQELIAJBCkcEQCAGEHILIAAgBxCSASAAIAMoAggQkwEgA0EQaiQADAELEJUBAAsgACACEJQBIAVBDGoQmgEgBUEQaiQAIAAQhQEaDAELIAAQhQEaIAMNACAAIgIgAUEBahCXAQwBCyAAKAIAIQIgACABQQFqEJQBCyABIAJqIgAgBEEPahCLASAEQQA6AA4gAEEBaiAEQQ5qEIsBIARBEGokAAsNACAAIAEgARBhEJkBC6wEAQZ/IwBBIGsiBCQAIARBDGoiBQJ/IARBIGoiAyAEQRVqIgJrIgZBCUwEQEE9IAZBICABQQFyZ2tB0QlsQQx1IgcgASAHQQJ0QfDUAGooAgBPakgNARoLAn8gAUG/hD1NBEAgAUGPzgBNBEAgAUHjAE0EQCABQQlNBEAgAiABEKABDAQLIAIgARChAQwDCyABQecHTQRAIAIgAUHkAG4iAhCgASABIAJB5ABsaxChAQwDCyACIAEQogEMAgsgAUGfjQZNBEAgAiABQZDOAG4iAhCgASABIAJBkM4AbGsQogEMAgsgAiABEKMBDAELIAFB/8HXL00EQCABQf+s4gRNBEAgAiABQcCEPW4iAhCgASABIAJBwIQ9bGsQowEMAgsgAiABEKQBDAELIAFB/5Pr3ANNBEAgAiABQYDC1y9uIgIQoAEgASACQYDC1y9saxCkAQwBCyACIAFBgMLXL24iAhChASABIAJBgMLXL2xrEKQBCyEDQQALNgIEIAUgAzYCACAEKAIMIQYjAEEQayICJAACQCAGIARBFWoiA2siBUH3////B00EQAJAIAUQlgEEQCAAIAUQlwEgACEBDAELIAJBCGogBRCNAUEBahCQASACKAIMGiAAIAIoAggiARCSASAAIAIoAgwQkwEgACAFEJQBCyABIAMgBiADayIDEJEBIAJBADoAByABIANqIAJBB2oQiwEgAkEQaiQADAELEJUBAAsgBEEgaiQACxEAIAAgAUEwajoAACAAQQFqC+sBAQV/IwBBEGsiBCQAIwBBIGsiAiQAIwBBEGsiAyQAIAMgAUEBdEGg1QBqIgEiBjYCDCADIAFBAmo2AgggAkEYaiADQQxqIANBCGoQpwEgA0EQaiQAIAIoAhghBSACKAIcIQMjAEEQayIBJAAgASADNgIMIAAgBSADIAVrIgMQiQEgASAAIANqNgIIIAJBEGogAUEMaiABQQhqEKYBIAFBEGokACACIAYgAigCEBClATYCDCACIAAgAigCFBClATYCCCAEQQhqIAJBDGogAkEIahCmASACQSBqJAAgBCgCDCEAIARBEGokACAACxsAIAAgAUHkAG4iABChASABIABB5ABsaxChAQsdACAAIAFBkM4AbiIAEKEBIAEgAEGQzgBsaxCiAQsdACAAIAFBwIQ9biIAEKEBIAEgAEHAhD1saxCjAQsKACAAIAEgAGtqCwsAIAAgASACEKcBCxYAIAAgASgCADYCACAAIAIoAgA2AgQLDgAgAEHQAGoQcUHQAGoLdAEBfyACRQRAIAAoAgQgASgCBEYPCyAAIAFGBEBBAQ8LIAEoAgQiAi0AACEBAkAgACgCBCIDLQAAIgBFDQAgACABRw0AA0AgAi0AASEBIAMtAAEiAEUNASACQQFqIQIgA0EBaiEDIAAgAUYNAAsLIAAgAUYLtQUBBn8jAEHQAGsiBCQAAkACf0EBIAAgAUEAEKkBDQAaQQAgAUUNABojAEEQayIFJAAgBUEEaiIDIAEoAgAiBkEIaygCACIHNgIIIAMgASAHajYCACADIAZBBGsoAgA2AgQgBSgCCCIGQZjXAEEAEKkBIQMgBSgCBCEHAkAgAwRAIAUoAgwhASMAQUBqIgMkACADQUBrJABBACAHIAEbIQMMAQsjAEFAaiIDJAAgASAHTgRAIANBHGoiCEIANwIAIANCADcCJCADQgA3AiwgA0IANwIUIANBADYCECADQZjXADYCDCADIAY2AgQgA0EANgI8IANCgYCAgICAgIABNwI0IAMgATYCCCAGIANBBGogByAHQQFBACAGKAIAKAIUEQoAIAFBACAIKAIAGyEICyADQUBrJAAgCCIDDQAjAEFAaiIDJAAgA0EANgIQIANB6NYANgIMIAMgATYCCCADQZjXADYCBEEAIQEgA0EUakEAQSf8CwAgA0EANgI8IANBAToAOyAGIANBBGogB0EBQQAgBigCACgCGBEIAAJAAkACQCADKAIoDgIAAQILIAMoAhhBACADKAIkQQFGG0EAIAMoAiBBAUYbQQAgAygCLEEBRhshAQwBCyADKAIcQQFHBEAgAygCLA0BIAMoAiBBAUcNASAD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dW50AGJhc2Vmb250AERvY3VtZW50AGltcG9ydGFudABkZWZhdWx0AHRpZ2h0AHJpZ2h0AEhpZ2hsaWdodABsZWZ0AGZyYW1lc2V0AGZpZWxkc2V0AGR0AFx0AGFkZHJlc3MAaHR0cHMAZGV0YWlscwBFbXBoYXNpcwBub2ZyYW1lcwAlczolZDogJXMAdHIAdmVjdG9yAGRpcgBocgBmb290ZXIAY2VudGVyAFNwb2lsZXIAaGVhZGVyAGZlbmNlQ2hhcgBccgBvcHRncm91cABjb2xncm91cABmdHAAL3NyYy9jcHAvd2FzbS9BU1RTZXJpYWxpemVyLmNwcAAvZW1zZGsvZW1zY3JpcHRlbi9zeXN0ZW0vbGliL2xpYmN4eGFiaS9zcmMvcHJpdmF0ZV90eXBlaW5mby5jcHAAdGlwAHZpZGVvAFZpZGVvAGNhdXRpb24Ab3B0aW9uAHN0ZDo6ZXhjZXB0aW9uAGZpZ2NhcHRpb24AQWRtb25pdGlvbgBzZWN0aW9uAG1haW4AYWxpZ24AbmFuAFxuAGZvcm0AbWVudWl0ZW0ATGlzdEl0ZW0AcGFyYW0AdWwAdXJsAGNvbABodG1sAFRhYmxlSGVhZGVyQ2VsbABUYWJsZUNlbGwAbGV2ZWwAZGwAaXNUYXNrAGxpbmsATGluawBDb2RlQmxvY2sAdHJhY2sAU29mdEJyZWFrAExpbmVCcmVhawBUaGVtYXRpY0JyZWFrAGxpAGJhZF9hcnJheV9uZXdfbGVuZ3RoAFBhcmFncmFwaABTdHJpa2V0aHJvdWdoAHNlYXJjaABkaWFsb2cAU3Ryb25nAGJhc2ljX3N0cmluZwBub2RlVHlwZVRvU3RyaW5nAHdhcm5pbmcASGVhZGluZwBpbmYAXGYAdHJ1ZQBibG9ja3F1b3RlAEJsb2NrcXVvdGUAbm90ZQBmYWxzZQBiYXNlAGZpZ3VyZQBhZG1vbml0aW9uVHlwZQBVbmRlcmxpbmUATGF0ZXhNYXRoSW5saW5lAEJsYW5rTGluZQBpZnJhbWUAdGl0bGUAYXJ0aWNsZQB0YWJsZQBUYWJsZQBJbWFnZQBDb2RlAGFzaWRlAHRkAGxlZ2VuZAB0YXNrQ2hlY2tlZABkZAB0aGVhZABUYWJsZUhlYWQAc3JjAHN0ZDo6YmFkX2FsbG9jAFxiACInPTw+YAAtXwAuLStfAFxcACh7WwAsImNoaWxkcmVuIjpbAE5BTgBJTkYAY2F0Y2hpbmcgYSBjbGFzcyB3aXRob3V0IGFuIG9iamVjdD8AXV0+AC0tPgBtYWlsdG86ACl9XS4hPyw7OgAsImNvbnRlbnQiOgBoNgBoNQBoNABoMwBoMgBoMQBodHRwOi8vAFRvbyBtYW55IGxpbmsgcmVmZXJlbmNlIGRlZmluaXRpb24gaW5zdGFudGlhdGlvbnMuAFVuc3VwcG9ydGVkIGFiaV92ZXJzaW9uLgBBYm9ydGVkIGZyb20gdGV4dCgpIGNhbGxiYWNrLgBBYm9ydGVkIGZyb20gZW50ZXJfc3BhbigpIGNhbGxiYWNrLgBBYm9ydGVkIGZyb20gbGVhdmVfc3BhbigpIGNhbGxiYWNrLgBBYm9ydGVkIGZyb20gZW50ZXJfYmxvY2soKSBjYWxsYmFjay4AQWJvcnRlZCBmcm9tIGxlYXZlX2Jsb2NrKCkgY2FsbGJhY2suAG1hbGxvYygpIGZhaWxlZC4AcmVhbGxvYygpIGZhaWxlZC4AQDouAC4hIyQlJicqKy89P15fYHt8fX4tAF8uOi0AKy0ALi1fKwAtXyoAKG51bGwpAFN1cHByZXNzaW5nIHRvbyBzcGFyc2UgdGFibGUgKHNlZSBodHRwczovL2dpdGh1Yi5jb20vbWl0eS9tZDRjL2lzc3Vlcy8zNDUpAC5fPSgpAC4rLV9+JSgpAGZhbHNlICYmICJ1bmhhbmRsZWQgTm9kZVR5cGUgaW4gbm9kZVR5cGVUb1N0cmluZyIAXCIAeyJ0eXBlIjoiAFtdIQB4WCAACgALBQAARQcAAKEEAAD2BgAAmAcAABUHAABrBwAAbwUAAE8HAADoBwAAMwgAAC0IAAC3BwAApgQAALQEAACoBgAA+wYAAB8HAAAnCAAAXQgAADIEAACLBAAAxwYAANcGAADyBwAAPAQAAKoFAADGBAAA0gQAADIFAAALBwAAAggAAHUGAABGBgBBkBcLfqgLAAATAAAAFAAAABUAAAAWAAAAFwAAAPgrAAC0CwAANCoAAE5TdDNfXzIyMF9fc2hhcmVkX3B0cl9lbXBsYWNlSU44TWFya2Rvd24xNU1hcmtkb3duQVNUTm9kZUVOU185YWxsb2NhdG9ySVMyX0VFRUUAPAUAAKMFAAAsBQBBsBgLEsIHAAA8BgAAFAUAAJAHAABMBgBB0BgLZsAMAADgDAAAEA0AAEANAAC4DAAAgA0AALgMAADADQAAIA4AALgMAAC4DAAAMA4AAFAOAABwDgAAkA4AALAOAAC4DAAAuAwAANAOAADwDgAAQA8AAFAPAAC4DAAAuAwAALgMAAC4DABBwBkLFVkFAAAHAAAAGQgAAAcAAAA4CAAABQBB4BkLHc0HAAAEAAAAAgUAAAgAAACsBwAACgAAAC0EAAAEAEGQGgsdbQYAAAcAAACjBQAABgAAAL4GAAADAAAAzwUAAAgAQcAaCzVUCAAAAgAAAGcFAAAHAAAAZAcAAAYAAACVBQAAAwAAAJQEAAADAAAA5wYAAAIAAABTBQAAAgBBgBsLNUoFAAAIAAAAagYAAAoAAADSBwAABgAAAJwFAAAGAAAAmgYAAAQAAAANCAAABQAAAEEFAAAIAEHAGwtNAgkAAAIAAAD/CAAAAgAAAPwIAAACAAAA+QgAAAIAAAD2CAAAAgAAAPMIAAACAAAAWAgAAAQAAACyBQAABgAAAJkFAAACAAAAwgYAAAQAQaAcCwUMCAAABgBBsBwLFUEIAAAGAAAALQcAAAIAAADxBgAABABB0BwLFYgGAAAEAAAAnAQAAAQAAACfBgAACABB8BwLDZgEAAADAAAAeAUAAAgAQZAdCxW/BgAAAgAAAMYFAAAIAAAAVAYAAAYAQbAdCw0+BgAAAQAAALEGAAAFAEHQHQsVXQcAAAYAAACABgAABwAAACQEAAAHAEHwHQtFIQgAAAUAAAAsBAAABQAAAD4IAAACAAAA3AQAAAUAAABCBwAAAgAAAFcIAAAFAAAAEwgAAAUAAACLBQAAAgAAAAUHAAAFAEHAHgsFtwYAAAIAQdAeCwVABgAABQBB4B4LlxMgAAAAoAAAAIAWAAAAIABACiAAgC8gAABfIAAAADAAAEEAAEBaAACAtQAAAMAAAEDWAACA2AAAQN4AAIAAAQBALgEAgDIBAEA2AQCAOQEAQEcBAIBKAQBAdgEAgHgBAAB5AQBAfQEAgH8BAACBAQAAggEAAIQBAACGAQAAhwEAAIkBAACKAQAAiwEAAI4BAACPAQAAkAEAAJEBAACTAQAAlAEAAJYBAACXAQAAmAEAAJwBAACdAQAAnwEAAKABAECkAQCApgEAAKcBAACpAQAArAEAAK4BAACvAQAAsQEAALIBAACzAQAAtQEAALcBAAC4AQAAvAEAAMQBAADFAQAAxwEAAMgBAADKAQAAywEAQNsBAIDeAQBA7gEAgPEBAADyAQAA9AEAAPYBAAD3AQAA+AEAQB4CAIAgAgAAIgIAQDICAIA6AgAAOwIAAD0CAAA+AgAAQQIAAEMCAABEAgAARQIAAEYCAEBOAgCARQMAAHADAAByAwAAdgMAAH8DAACGAwAAiAMAQIoDAICMAwAAjgMAAI8DAACRAwBAoQMAgKMDAECrAwCAwgMAAM8DAADQAwAA0QMAANUDAADWAwAA2AMAQO4DAIDwAwAA8QMAAPQDAAD1AwAA9wMAAPkDAAD6AwAA/QMAQP8DAIAABABADwQAgBAEAEAvBACAYAQAQIAEAICKBABAvgQAgMAEAADBBABAzQQAgNAEAEAuBQCAMQUAQFYFAICgEABAxRAAgMcQAADNEAAA+BMAQP0TAICAHAAAgRwAAIIcAACDHAAAhBwAAIUcAACGHAAAhxwAAIgcAACJHAAAkBwAQLocAIC9HABAvxwAgAAeAECUHgCAmx4AAKAeAED+HgCACB8AQA8fAIAYHwBAHR8AgCgfAEAvHwCAOB8AQD8fAIBIHwBATR8AgFkfAABbHwAAXR8AAF8fAABoHwBAbx8AgLgfAAC5HwAAuh8AALsfAAC+HwAAyB8AQMsfAIDYHwAA2R8AANofAADbHwAA6B8AAOkfAADqHwAA6x8AAOwfAAD4HwAA+R8AAPofAAD7HwAAJiEAACohAAArIQAAMiEAAGAhAEBvIQCAgyEAALYkAEDPJACAACwAQC8sAIBgLAAAYiwAAGMsAABkLAAAZywAQGssAIBtLAAAbiwAAG8sAABwLAAAciwAAHUsAAB+LAAAfywAAIAsAEDiLACA6ywAAO0sAADyLAAAQKYAQGymAICApgBAmqYAgCKnAEAupwCAMqcAQG6nAIB5pwAAe6cAAH2nAAB+pwBAhqcAgIunAACNpwAAkKcAAJKnAACWpwBAqKcAgKqnAACrpwAArKcAAK2nAACupwAAsKcAALGnAACypwAAs6cAALSnAEDCpwCAxKcAAMWnAADGpwAAx6cAAMmnAADLpwAAzKcAQNqnAIDcpwAA3acAAOKnAAD1pwAAbKsAAG2rAABwqwBAv6sAgCH/AEA6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"); } function getBinarySync(file) { - return file; -@@ -117,7 +118,7 @@ var createMd4cModule = (() => { - return imports; +- return file; ++ if (ArrayBuffer.isView(file)) { ++ return file; ++ } ++ if (file == wasmBinaryFile && wasmBinary) { ++ return new Uint8Array(wasmBinary); ++ } ++ if (readBinary) { ++ return readBinary(file); ++ } ++ throw "both async and sync fetching of the wasm failed"; + } + async function getWasmBinary(binaryFile) { + return getBinarySync(binaryFile); +@@ -110,27 +131,30 @@ var createMd4cModule = (() => { + return instantiateArrayBuffer(binaryFile, imports); + } + function getWasmImports() { +- var imports = { ++ return { + env: wasmImports, + wasi_snapshot_preview1: wasmImports + }; +- return imports; } async function createWasm() { - function receiveInstance(instance) { + function receiveInstance(instance, module) { wasmExports = instance.exports; - assignWasmExports(wasmExports); +- assignWasmExports(wasmExports); ++ wasmMemory = wasmExports["memory"]; updateMemoryViews(); -@@ -127,10 +128,11 @@ var createMd4cModule = (() => { ++ assignWasmExports(wasmExports); ++ removeRunDependency("wasm-instantiate"); + return wasmExports; + } ++ addRunDependency("wasm-instantiate"); + function receiveInstantiationResult(result) { return receiveInstance(result["instance"]); } var info = getWasmImports(); @@ -1471,13 +1574,13 @@ index 978a8c7..950cccd 100644 - instantiateWasm(info, inst => resolve(receiveInstance(inst))); + if (Module["instantiateWasm"]) { + return new Promise((resolve, reject) => { -+ Module["instantiateWasm"](info, (inst, mod) => { -+ resolve(receiveInstance(inst, mod)); ++ Module["instantiateWasm"](info, (mod, inst) => { ++ resolve(receiveInstance(mod, inst)); + }); }); } wasmBinaryFile ??= findWasmBinary(); -@@ -145,23 +147,15 @@ var createMd4cModule = (() => { +@@ -145,35 +169,39 @@ var createMd4cModule = (() => { this.status = status; } } @@ -1500,10 +1603,52 @@ index 978a8c7..950cccd 100644 + var addOnPostRun = cb => onPostRuns.push(cb); var onPreRuns = []; + var addOnPreRun = cb => onPreRuns.push(cb); ++ var base64Decode = b64 => { ++ var b1, ++ b2, ++ i = 0, ++ j = 0, ++ bLength = b64.length; ++ var output = new Uint8Array((bLength * 3 >> 2) - (b64[bLength - 2] == "=") - (b64[bLength - 1] == "=")); ++ for (; i < bLength; i += 4, j += 3) { ++ b1 = base64ReverseLookup[b64.charCodeAt(i + 1)]; ++ b2 = base64ReverseLookup[b64.charCodeAt(i + 2)]; ++ output[j] = base64ReverseLookup[b64.charCodeAt(i)] << 2 | b1 >> 4; ++ output[j + 1] = b1 << 4 | b2 >> 2; ++ output[j + 2] = b2 << 6 | base64ReverseLookup[b64.charCodeAt(i + 3)]; ++ } ++ return output; ++ }; var noExitRuntime = true; var stackRestore = val => __emscripten_stack_restore(val); var stackSave = () => _emscripten_stack_get_current(); -@@ -249,12 +243,14 @@ var createMd4cModule = (() => { +- var UTF8Decoder = globalThis.TextDecoder && new TextDecoder(); +- var findStringEnd = (heapOrArray, idx, maxBytesToRead, ignoreNul) => { +- var maxIdx = idx + maxBytesToRead; +- if (ignoreNul) return maxIdx; +- while (heapOrArray[idx] && !(idx >= maxIdx)) ++idx; +- return idx; +- }; +- var UTF8ArrayToString = (heapOrArray, idx = 0, maxBytesToRead, ignoreNul) => { +- var endPtr = findStringEnd(heapOrArray, idx, maxBytesToRead, ignoreNul); ++ var UTF8Decoder = typeof TextDecoder != "undefined" ? new TextDecoder() : undefined; ++ var UTF8ArrayToString = (heapOrArray, idx = 0, maxBytesToRead = NaN) => { ++ var endIdx = idx + maxBytesToRead; ++ var endPtr = idx; ++ while (heapOrArray[endPtr] && !(endPtr >= endIdx)) ++endPtr; + if (endPtr - idx > 16 && heapOrArray.buffer && UTF8Decoder) { + return UTF8Decoder.decode(heapOrArray.subarray(idx, endPtr)); + } +@@ -204,7 +232,7 @@ var createMd4cModule = (() => { + } + return str; + }; +- var UTF8ToString = (ptr, maxBytesToRead, ignoreNul) => ptr ? UTF8ArrayToString(HEAPU8, ptr, maxBytesToRead, ignoreNul) : ""; ++ var UTF8ToString = (ptr, maxBytesToRead) => ptr ? UTF8ArrayToString(HEAPU8, ptr, maxBytesToRead) : ""; + var ___assert_fail = (condition, filename, line, func) => abort(`Assertion failed: ${UTF8ToString(condition)}, at: ` + [filename ? UTF8ToString(filename) : "unknown filename", line, func ? UTF8ToString(func) : "unknown function"]); + class ExceptionInfo { + constructor(excPtr) { +@@ -249,19 +277,21 @@ var createMd4cModule = (() => { return HEAPU32[this.ptr + 16 >> 2]; } } @@ -1519,7 +1664,16 @@ index 978a8c7..950cccd 100644 }; var __abort_js = () => abort(""); var getHeapMax = () => 536870912; -@@ -400,17 +396,24 @@ var createMd4cModule = (() => { + var alignMemory = (size, alignment) => Math.ceil(size / alignment) * alignment; + var growMemory = size => { +- var oldHeapSize = wasmMemory.buffer.byteLength; +- var pages = (size - oldHeapSize + 65535) / 65536 | 0; ++ var b = wasmMemory.buffer; ++ var pages = (size - b.byteLength + 65535) / 65536 | 0; + try { + wasmMemory.grow(pages); + updateMemoryViews(); +@@ -400,31 +430,30 @@ var createMd4cModule = (() => { } return (...args) => ccall(ident, returnType, argTypes, args, opts); }; @@ -1543,19 +1697,36 @@ index 978a8c7..950cccd 100644 - if (typeof preInit == "function") Module["preInit"] = preInit = [preInit]; - while (preInit.length > 0) { - preInit.shift()(); -+ if (Module["preInit"]) { -+ if (typeof Module["preInit"] == "function") Module["preInit"] = [Module["preInit"]]; -+ while (Module["preInit"].length > 0) { -+ Module["preInit"].shift()(); - } - } +- } +- } } -@@ -432,24 +435,39 @@ var createMd4cModule = (() => { + Module["ccall"] = ccall; + Module["cwrap"] = cwrap; + Module["UTF8ToString"] = UTF8ToString; +- var _parseMarkdown, __emscripten_stack_restore, __emscripten_stack_alloc, _emscripten_stack_get_current, memory, __indirect_function_table, wasmMemory; ++ var _parseMarkdown, __emscripten_stack_restore, __emscripten_stack_alloc, _emscripten_stack_get_current; + function assignWasmExports(wasmExports) { +- _parseMarkdown = Module["_parseMarkdown"] = wasmExports["parseMarkdown"]; ++ Module["_parseMarkdown"] = _parseMarkdown = wasmExports["parseMarkdown"]; + __emscripten_stack_restore = wasmExports["_emscripten_stack_restore"]; + __emscripten_stack_alloc = wasmExports["_emscripten_stack_alloc"]; + _emscripten_stack_get_current = wasmExports["emscripten_stack_get_current"]; +- memory = wasmMemory = wasmExports["memory"]; +- __indirect_function_table = wasmExports["__indirect_function_table"]; + } + var wasmImports = { + __assert_fail: ___assert_fail, +@@ -432,28 +461,58 @@ var createMd4cModule = (() => { _abort_js: __abort_js, emscripten_resize_heap: _emscripten_resize_heap }; - async function run() { ++ var wasmExports = await createWasm(); + function run() { ++ if (runDependencies > 0) { ++ dependenciesFulfilled = run; ++ return; ++ } preRun(); - var setStatus = Module["setStatus"]; - if (setStatus) { @@ -1567,6 +1738,10 @@ index 978a8c7..950cccd 100644 - initRuntime(); - Module["onRuntimeInitialized"]?.(); - postRun(); ++ if (runDependencies > 0) { ++ dependenciesFulfilled = run; ++ return; ++ } + function doRun() { + Module["calledRun"] = true; + if (ABORT) return; @@ -1584,10 +1759,16 @@ index 978a8c7..950cccd 100644 + } else { + doRun(); + } - } - var wasmExports; - wasmExports = await createWasm(); -- await run(); ++ } ++ function preInit() { ++ if (Module["preInit"]) { ++ if (typeof Module["preInit"] == "function") Module["preInit"] = [Module["preInit"]]; ++ while (Module["preInit"].length > 0) { ++ Module["preInit"].shift()(); ++ } ++ } ++ } ++ preInit(); + run(); + if (runtimeInitialized) { + moduleRtn = Module; @@ -1596,20 +1777,31 @@ index 978a8c7..950cccd 100644 + readyPromiseResolve = resolve; + readyPromiseReject = reject; + }); -+ } - ; + } +- var wasmExports; +- wasmExports = await createWasm(); +- await run(); +- ; - return Module; + return moduleRtn; }; })(); - if (typeof exports === "object" && typeof module === "object") { +-if (typeof exports === "object" && typeof module === "object") { ++if (typeof exports === 'object' && typeof module === 'object') { + module.exports = createMd4cModule; + module.exports.default = createMd4cModule; +-} else if (typeof define === "function" && define["amd"]) define([], () => createMd4cModule); ++} else if (typeof define === 'function' && define['amd']) define([], () => createMd4cModule); + //# sourceMappingURL=md4c.js.map +\ No newline at end of file diff --git a/node_modules/react-native-enriched-markdown/lib/module/web/wasm/md4c.js.map b/node_modules/react-native-enriched-markdown/lib/module/web/wasm/md4c.js.map -index 75b509c..ecbb5e7 100644 +index 75b509cd2..c68da0c05 100644 --- a/node_modules/react-native-enriched-markdown/lib/module/web/wasm/md4c.js.map +++ b/node_modules/react-native-enriched-markdown/lib/module/web/wasm/md4c.js.map @@ -1 +1 @@ -{"version":3,"names":["createMd4cModule","_scriptName","globalThis","document","currentScript","src","moduleArg","Module","ENVIRONMENT_IS_WEB","ENVIRONMENT_IS_WORKER","programArgs","thisProgram","scriptDirectory","readAsync","URL","href","url","response","fetch","credentials","ok","arrayBuffer","Error","status","out","console","log","bind","err","error","wasmBinary","ABORT","EmscriptenEH","EmscriptenSjLj","binaryDecode","bin","i","l","length","o","Uint8Array","c","charCodeAt","runtimeInitialized","getMemoryBuffer","wasmMemory","buffer","updateMemoryViews","HEAP8","resizable","b","Int8Array","HEAP16","Int16Array","HEAPU8","HEAPU16","Uint16Array","HEAP32","Int32Array","HEAPU32","Uint32Array","HEAPF32","Float32Array","HEAPF64","Float64Array","HEAP64","BigInt64Array","HEAPU64","BigUint64Array","preRun","onPreRuns","push","callRuntimeCallbacks","initRuntime","wasmExports","postRun","onPostRuns","abort","what","e","WebAssembly","RuntimeError","wasmBinaryFile","findWasmBinary","getBinarySync","file","getWasmBinary","binaryFile","instantiateArrayBuffer","imports","binary","instance","instantiate","reason","instantiateAsync","getWasmImports","env","wasmImports","wasi_snapshot_preview1","createWasm","receiveInstance","exports","assignWasmExports","receiveInstantiationResult","result","info","instantiateWasm","Promise","resolve","inst","ExitStatus","name","constructor","message","callbacks","shift","noExitRuntime","stackRestore","val","__emscripten_stack_restore","stackSave","_emscripten_stack_get_current","UTF8Decoder","TextDecoder","findStringEnd","heapOrArray","idx","maxBytesToRead","ignoreNul","maxIdx","UTF8ArrayToString","endPtr","decode","subarray","str","u0","String","fromCharCode","u1","u2","ch","UTF8ToString","ptr","___assert_fail","condition","filename","line","func","ExceptionInfo","excPtr","set_type","type","get_type","set_destructor","destructor","get_destructor","set_caught","caught","get_caught","set_rethrown","rethrown","get_rethrown","init","set_adjusted_ptr","adjustedPtr","get_adjusted_ptr","uncaughtExceptionCount","___cxa_throw","__abort_js","getHeapMax","alignMemory","size","alignment","Math","ceil","growMemory","oldHeapSize","byteLength","pages","grow","_emscripten_resize_heap","requestedSize","oldSize","maxHeapSize","cutDown","overGrownHeapSize","min","newSize","max","replacement","getCFunc","ident","writeArrayToMemory","array","set","lengthBytesUTF8","len","stringToUTF8Array","heap","outIdx","maxBytesToWrite","startIdx","endIdx","u","codePointAt","stringToUTF8","outPtr","stackAlloc","sz","__emscripten_stack_alloc","stringToUTF8OnStack","ret","ccall","returnType","argTypes","args","opts","toC","string","undefined","arr","convertReturnValue","Boolean","cArgs","stack","converter","onDone","cwrap","numericArgs","every","numericRet","preInit","_parseMarkdown","memory","__indirect_function_table","__assert_fail","__cxa_throw","_abort_js","emscripten_resize_heap","run","setStatus","setTimeout","module","default","define"],"sourceRoot":"../../../../src","sources":["web/wasm/md4c.js"],"mappings":"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","ignoreList":[]} -+{"version":3,"names":["createMd4cModule","_scriptName","globalThis","document","currentScript","src","moduleArg","moduleRtn","Module","ENVIRONMENT_IS_WEB","ENVIRONMENT_IS_WORKER","arguments_","thisProgram","scriptDirectory","readAsync","URL","href","url","response","fetch","credentials","ok","arrayBuffer","Error","status","out","console","log","bind","err","error","wasmBinary","ABORT","binaryDecode","bin","i","l","length","o","Uint8Array","c","charCodeAt","readyPromiseResolve","readyPromiseReject","HEAP8","HEAPU8","HEAP16","HEAPU16","HEAP32","HEAPU32","HEAPF32","HEAPF64","HEAP64","HEAPU64","runtimeInitialized","updateMemoryViews","b","wasmMemory","buffer","Int8Array","Int16Array","Uint16Array","Int32Array","Uint32Array","Float32Array","Float64Array","BigInt64Array","BigUint64Array","preRun","addOnPreRun","shift","callRuntimeCallbacks","onPreRuns","initRuntime","wasmExports","postRun","addOnPostRun","onPostRuns","abort","what","e","WebAssembly","RuntimeError","wasmBinaryFile","findWasmBinary","getBinarySync","file","getWasmBinary","binaryFile","instantiateArrayBuffer","imports","binary","instance","instantiate","reason","instantiateAsync","getWasmImports","env","wasmImports","wasi_snapshot_preview1","createWasm","receiveInstance","module","exports","assignWasmExports","receiveInstantiationResult","result","info","Promise","resolve","reject","inst","mod","ExitStatus","name","constructor","message","callbacks","cb","push","noExitRuntime","stackRestore","val","__emscripten_stack_restore","stackSave","_emscripten_stack_get_current","UTF8Decoder","TextDecoder","findStringEnd","heapOrArray","idx","maxBytesToRead","ignoreNul","maxIdx","UTF8ArrayToString","endPtr","decode","subarray","str","u0","String","fromCharCode","u1","u2","ch","UTF8ToString","ptr","___assert_fail","condition","filename","line","func","ExceptionInfo","excPtr","set_type","type","get_type","set_destructor","destructor","get_destructor","set_caught","caught","get_caught","set_rethrown","rethrown","get_rethrown","init","set_adjusted_ptr","adjustedPtr","get_adjusted_ptr","exceptionLast","uncaughtExceptionCount","___cxa_throw","__abort_js","getHeapMax","alignMemory","size","alignment","Math","ceil","growMemory","oldHeapSize","byteLength","pages","grow","_emscripten_resize_heap","requestedSize","oldSize","maxHeapSize","cutDown","overGrownHeapSize","min","newSize","max","replacement","getCFunc","ident","writeArrayToMemory","array","set","lengthBytesUTF8","len","stringToUTF8Array","heap","outIdx","maxBytesToWrite","startIdx","endIdx","u","codePointAt","stringToUTF8","outPtr","stackAlloc","sz","__emscripten_stack_alloc","stringToUTF8OnStack","ret","ccall","returnType","argTypes","args","opts","toC","string","undefined","arr","convertReturnValue","Boolean","cArgs","stack","converter","onDone","cwrap","numericArgs","every","numericRet","base64ReverseLookup","_parseMarkdown","memory","__indirect_function_table","__assert_fail","__cxa_throw","_abort_js","emscripten_resize_heap","run","doRun","setTimeout","default","define"],"sourceRoot":"../../../../src","sources":["web/wasm/md4c.js"],"mappings":"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","ignoreList":[]} ++{"version":3,"names":["createMd4cModule","_scriptName","document","currentScript","src","undefined","moduleArg","moduleRtn","Module","ENVIRONMENT_IS_WEB","ENVIRONMENT_IS_WORKER","arguments_","thisProgram","scriptDirectory","readAsync","readBinary","URL","href","url","response","fetch","credentials","ok","arrayBuffer","Error","status","out","console","log","bind","err","error","wasmBinary","ABORT","readyPromiseResolve","readyPromiseReject","wasmMemory","HEAP8","HEAPU8","HEAP16","HEAPU16","HEAP32","HEAPU32","HEAPF32","HEAPF64","HEAP64","HEAPU64","runtimeInitialized","updateMemoryViews","b","buffer","Int8Array","Int16Array","Uint8Array","Uint16Array","Int32Array","Uint32Array","Float32Array","Float64Array","BigInt64Array","BigUint64Array","preRun","length","addOnPreRun","shift","callRuntimeCallbacks","onPreRuns","initRuntime","wasmExports","postRun","addOnPostRun","onPostRuns","runDependencies","dependenciesFulfilled","addRunDependency","id","removeRunDependency","callback","abort","what","e","WebAssembly","RuntimeError","wasmBinaryFile","findWasmBinary","base64Decode","getBinarySync","file","ArrayBuffer","isView","getWasmBinary","binaryFile","instantiateArrayBuffer","imports","binary","instance","instantiate","reason","instantiateAsync","getWasmImports","env","wasmImports","wasi_snapshot_preview1","createWasm","receiveInstance","module","exports","assignWasmExports","receiveInstantiationResult","result","info","Promise","resolve","reject","mod","inst","ExitStatus","name","constructor","message","callbacks","cb","push","b64","b1","b2","i","j","bLength","output","base64ReverseLookup","charCodeAt","noExitRuntime","stackRestore","val","__emscripten_stack_restore","stackSave","_emscripten_stack_get_current","UTF8Decoder","TextDecoder","UTF8ArrayToString","heapOrArray","idx","maxBytesToRead","NaN","endIdx","endPtr","decode","subarray","str","u0","String","fromCharCode","u1","u2","ch","UTF8ToString","ptr","___assert_fail","condition","filename","line","func","ExceptionInfo","excPtr","set_type","type","get_type","set_destructor","destructor","get_destructor","set_caught","caught","get_caught","set_rethrown","rethrown","get_rethrown","init","set_adjusted_ptr","adjustedPtr","get_adjusted_ptr","exceptionLast","uncaughtExceptionCount","___cxa_throw","__abort_js","getHeapMax","alignMemory","size","alignment","Math","ceil","growMemory","pages","byteLength","grow","_emscripten_resize_heap","requestedSize","oldSize","maxHeapSize","cutDown","overGrownHeapSize","min","newSize","max","replacement","getCFunc","ident","writeArrayToMemory","array","set","lengthBytesUTF8","len","c","stringToUTF8Array","heap","outIdx","maxBytesToWrite","startIdx","u","codePointAt","stringToUTF8","outPtr","stackAlloc","sz","__emscripten_stack_alloc","stringToUTF8OnStack","ret","ccall","returnType","argTypes","args","opts","toC","string","arr","convertReturnValue","Boolean","cArgs","stack","converter","onDone","cwrap","numericArgs","every","numericRet","_parseMarkdown","__assert_fail","__cxa_throw","_abort_js","emscripten_resize_heap","run","doRun","setTimeout","preInit","default","define"],"sourceRoot":"../../../src","sources":["web/wasm/md4c.js"],"sourcesContent":["\"use strict\";\nvar createMd4cModule = (() => {\n var _scriptName = typeof document != 'undefined' ? document.currentScript?.src : undefined;\n return (\nasync function(moduleArg = {}) {\n var moduleRtn;\n\nvar Module=moduleArg;var ENVIRONMENT_IS_WEB=true;var ENVIRONMENT_IS_WORKER=false;var arguments_=[];var thisProgram=\"./this.program\";var scriptDirectory=\"\";var readAsync,readBinary;if(ENVIRONMENT_IS_WEB||ENVIRONMENT_IS_WORKER){try{scriptDirectory=new URL(\".\",_scriptName).href}catch{}{readAsync=async url=>{var response=await fetch(url,{credentials:\"same-origin\"});if(response.ok){return response.arrayBuffer()}throw new Error(response.status+\" : \"+response.url)}}}else{}var out=console.log.bind(console);var err=console.error.bind(console);var wasmBinary;var ABORT=false;var readyPromiseResolve,readyPromiseReject;var wasmMemory;var HEAP8,HEAPU8,HEAP16,HEAPU16,HEAP32,HEAPU32,HEAPF32,HEAPF64;var HEAP64,HEAPU64;var runtimeInitialized=false;function updateMemoryViews(){var b=wasmMemory.buffer;HEAP8=new Int8Array(b);HEAP16=new Int16Array(b);HEAPU8=new Uint8Array(b);HEAPU16=new Uint16Array(b);HEAP32=new Int32Array(b);HEAPU32=new Uint32Array(b);HEAPF32=new Float32Array(b);HEAPF64=new Float64Array(b);HEAP64=new BigInt64Array(b);HEAPU64=new BigUint64Array(b)}function preRun(){if(Module[\"preRun\"]){if(typeof Module[\"preRun\"]==\"function\")Module[\"preRun\"]=[Module[\"preRun\"]];while(Module[\"preRun\"].length){addOnPreRun(Module[\"preRun\"].shift())}}callRuntimeCallbacks(onPreRuns)}function initRuntime(){runtimeInitialized=true;wasmExports[\"__wasm_call_ctors\"]()}function postRun(){if(Module[\"postRun\"]){if(typeof Module[\"postRun\"]==\"function\")Module[\"postRun\"]=[Module[\"postRun\"]];while(Module[\"postRun\"].length){addOnPostRun(Module[\"postRun\"].shift())}}callRuntimeCallbacks(onPostRuns)}var runDependencies=0;var dependenciesFulfilled=null;function addRunDependency(id){runDependencies++;Module[\"monitorRunDependencies\"]?.(runDependencies)}function removeRunDependency(id){runDependencies--;Module[\"monitorRunDependencies\"]?.(runDependencies);if(runDependencies==0){if(dependenciesFulfilled){var callback=dependenciesFulfilled;dependenciesFulfilled=null;callback()}}}function abort(what){Module[\"onAbort\"]?.(what);what=\"Aborted(\"+what+\")\";err(what);ABORT=true;what+=\". Build with -sASSERTIONS for more info.\";var e=new WebAssembly.RuntimeError(what);readyPromiseReject?.(e);throw e}var wasmBinaryFile;function findWasmBinary(){return base64Decode(\"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8AFrIgMkAAJAAkAgAkUEQEEBIQkMAQsCQAJAAkACQAJAAkACQAJAAkACQAJAAkACQCAADhACAQAGBA0FBwgNAwkKCw0MDQtBPBB/IgBCADcCECAAQQM2AgwgAEGUFzYCACAAQgA3AgQgAEIANwI0IABCgICA/AM3AiwgAEIANwIYIABCADcCICAAQQA2AiggAEEMaiEGAkAgAUUNAAJAAkAgASgCBCIEBEAgASgCACIHDQELIANBADYC6AEgA0IANwPgAQwBCyAEQfj///8HTw0PAkAgBEELTwRAIARBB3IiCEEBahB/IQUgAyAIQf////8HazYC6AEgAyAFNgLgASADIAQ2AuQBDAELIAMgBDoA6wEgA0HgAWohBQsgBARAIAUgByAE/AoAAAsgBCAFakEAOgAAIAMoAuQBIAMtAOsBIgQgBMBBAEgbRQ0AIAZBkNwAIANB4AFqEBoLAkACQCABKAIUIgQEQCABKAIQIgUNAQsgA0EANgLYASADQgA3A9ABDAELIARB+P///wdPDQ8CQCAEQQtPBEAgBEEHciIHQQFqEH8hASADIAdB/////wdrNgLYASADIAE2AtABIAMgBDYC1AEMAQsgAyAEOgDbASADQdABaiEBCyAEBEAgASAFIAT8CgAACyABIARqQQA6AAAgAygC1AEgAy0A2wEiASABwEEASBtFDQAgBkGc3AAgA0HQAWoQGgsgAywA2wFBAEgEQCADKALYARogAygC0AEQcgsgAywA6wFBAE4NACADKALoARogAygC4AEQcgsgAyAANgLMASADIAY2AsgBIAAgACgCBEEBajYCBCADIAMpAsgBNwMAIAIgAxAYIAAgACgCBCICQQFrNgIEIAINDCAAIAAoAgAoAggRAQAgABB8DAwLQTwQfyIAQgA3AhAgAEEGNgIMIABBlBc2AgAgAEIANwIEIABCADcCNCAAQoCAgPwDNwIsIABCADcCGCAAQgA3AiAgAEEANgIoIAMgADYCxAEgAyAAQQxqNgLAASADIAMpAsABNwMIIAIgA0EIahAYDAsLQTwQfyIAQgA3AhAgAEEHNgIMIABBlBc2AgAgAEIANwIEIABCADcCNCAAQoCAgPwDNwIsIABCADcCGCAAQgA3AiAgAEEANgIoIAMgADYCvAEgAyAAQQxqNgK4ASADIAMpArgBNwMQIAIgA0EQahAYDAoLQTwQfyIAQgA3AhAgAEEJNgIMIABBlBc2AgAgAEIANwIEIABCADcCNCAAQoCAgPwDNwIsIABCADcCGCAAQgA3AiAgAEEANgIoIAMgADYCtAEgAyAAQQxqNgKwASADIAMpArABNwMYIAIgA0EYahAYDAkLQTwQfyIAQgA3AhAgAEEKNgIMIABBlBc2AgAgAEIANwIEIABCADcCNCAAQoCAgPwDNwIsIABCADcCGCAAQgA3AiAgAEEANgIoIAMgADYCrAEgAyAAQQxqNgKoASADIAMpAqgBNwMgIAIgA0EgahAYDAgLQTwQfyIAQgA3AhAgAEEINgIMIABBlBc2AgAgAEIANwIEIABCADcCNCAAQoCAgPwDNwIsIABCADcCGCAAQgA3AiAgAEEANgIoIAMgADYCpAEgAyAAQQxqNgKgASADIAMpAqABNwMoIAIgA0EoahAYDAcLQTwQfyIAQgA3AhAgAEELNgIMIABBlBc2AgAgAEIANwIEIABCADcCNCAAQoCAgPwDNwIsIABCADcCGCAAQgA3AiAgAEEANgIoIABBDGohBgJAIAFFDQACQAJAIAEoAgQiBARAIAEoAgAiBw0BCyADQQA2AugBIANCADcD4AEMAQsgBEH4////B08NCQJAIARBC08EQCAEQQdyIghBAWoQfyEFIAMgCEH/////B2s2AugBIAMgBTYC4AEgAyAENgLkAQwBCyADIAQ6AOsBIANB4AFqIQULIAQEQCAFIAcgBPwKAAALIAQgBWpBADoAACADKALkASADLQDrASIEIATAQQBIG0UNACAGQZDcACADQeABahAaCwJAAkAgASgCFCIEBEAgASgCECIFDQELIANBADYC2AEgA0IANwPQAQwBCyAEQfj///8HTw0JAkAgBEELTwRAIARBB3IiB0EBahB/IQEgAyAHQf////8HazYC2AEgAyABNgLQASADIAQ2AtQBDAELIAMgBDoA2wEgA0HQAWohAQsgBARAIAEgBSAE/AoAAAsgASAEakEAOgAAIAMoAtQBIAMtANsBIgEgAcBBAEgbRQ0AIAZBnNwAIANB0AFqEBoLIAMsANsBQQBIBEAgAygC2AEaIAMoAtABEHILIAMsAOsBQQBODQAgAygC6AEaIAMoAuABEHILIAMgADYCnAEgAyAGNgKYASAAIAAoAgRBAWo2AgQgAyADKQKYATcDMCACIANBMGoQGCAAIAAoAgQiAkEBazYCBCACDQYgACAAKAIAKAIIEQEAIAAQfAwGC0E8EH8iAEIANwIQIABBGDYCDCAAQZQXNgIAIABCADcCBCAAQgA3AjQgAEKAgID8AzcCLCAAQgA3AhggAEIANwIgIABBADYCKCADIAA2ApQBIAMgAEEMajYCkAEgAyADKQKQATcDOCACIANBOGoQGAwFC0E8EH8iAEIANwIQIABBGTYCDCAAQZQXNgIAIABCADcCBCAAQgA3AjQgAEKAgID8AzcCLCAAQgA3AhggAEIANwIgIABBADYCKCADIAA2AowBIAMgAEEMajYCiAEgAyADKQKIATcDQCACIANBQGsQGAwEC0E8EH8iAEIANwIQIABBGjYCDCAAQZQXNgIAIABCADcCBCAAQgA3AjQgAEKAgID8AzcCLCAAQgA3AhggAEIANwIgIABBADYCKCADIAA2AoQBIAMgAEEMajYCgAEgAyADKQKAATcDSCACIANByABqEBgMAwtBPBB/IgBCADcCECAAQRs2AgwgAEGUFzYCACAAQgA3AgQgAEIANwI0IABCgICA/AM3AiwgAEIANwIYIABCADcCICAAQQA2AiggAyAANgJ8IAMgAEEMajYCeCADIAMpAng3A1AgAiADQdAAahAYDAILQTwQfyIAQgA3AhAgAEEcNgIMIABBlBc2AgAgAEIANwIEIABCADcCNCAAQoCAgPwDNwIsIABCADcCGCAAQgA3AiAgAEEANgIoIAMgADYCdCADIABBDGo2AnAgAyADKQJwNwNYIAIgA0HYAGoQGAwBC0E8EH8iAEIANwIQIABBHTYCDCAAQZQXNgIAIABCADcCBCAAQgA3AjQgAEKAgID8AzcCLCAAQgA3AhggAEIANwIgIABBADYCKCADIAA2AmwgAyAAQQxqNgJoIAMgAykCaDcDYCACIANB4ABqEBgLIANB8AFqJAAgCQ8LEAcAC9cYAQp/IwBB4ABrIgMkAAJAIAJFBEBBASEADAELAkACQCAADgkCAQEBAQEBAQABC0EAIQAgAkEAOgAkIANCADcDGCADQgA3AxAgA0KAgICAgICAwD83AyAgA0IANwMIAkAgAigCLCACLAAzIgQgBEEASCIBGyIFRQ0AIAJBKGoiBigCACIHIAYgARshAQNAIAAgAWotAAAQUwRAIABBAWoiACAFRw0BDAILCyAHIAYgBEEASBsgAGotAABBPEcNAAJAIABBAWoiACAFTw0AIAcgBiAEQQBIGyIBIABqLQAAQS9GDQEDQCAAIAFqLQAAEFNFDQEgAEEBaiIAIAVHDQALDAELIAAgBU8NACAHIAYgBEEASBshByAAIQECQANAIAEgB2oiBC0AABBTDQEgBC0AAEE+Rg0BIAQtAABBL0YNASABQQFqIgEgBUcNAAsgBSEBCyAAIAFGDQAgA0EIaiABIABrEJgBIAAgAUkEQANAIANBCGogAigCKCAGIAIsADNBAEgbIABqLQAAEGLAEJ0BIABBAWoiACABRw0ACwsgASACKAIsIgggAiwAMyIJIAlBAEgbIgBPDQAgCUEfdiEFIANBFGohCiADQdAAaiELA0AgBigCACAGIAVBAXEbIQUDQCABIAVqIgQtAAAQUwRAIAFBAWoiASAASQ0BDAMLCyAELQAAQT5GDQEgBC0AAEEvRg0BAkACQCAAIAFLBEAgASEEAkADQCAEIAVqIgctAABBPUYNASAHLQAAEFMNASAHLQAAQT5GDQEgBy0AAEEvRg0BIARBAWoiBCAASQ0ACyAAIQQLIAEgBEcNAQsgAUEBaiEBDAELIAtBADYCACADQgA3A0ggA0HIAGogBCABaxCYASABIARJBEADQCADQcgAaiACKAIoIAYgAiwAM0EASBsgAWotAAAQYsAQnQEgAUEBaiIBIARJDQALCwJAAn8CQCAEIAIoAiwgAiwAMyIAIABBAEgiBRsiAE8NACAGKAIAIAYgBRshBQJAA0AgBCAFaiIBLQAAEFNFDQEgBEEBaiIEIABHDQALIAAMAgsgAS0AAEE9Rw0AAkACQAJAAkACQANAIAAgBCIHQQFqIgRNDQEgBCAFaiIBLQAAEFMNAAsgA0FAayIJQQA2AgAgA0IANwM4AkAgAS0AAEEiRg0AIAEtAABBJ0YNACAEIQEDQCABIAVqIgktAAAQUw0DIAktAABBPkYNAyAJLQAAQS9GDQMgAUEBaiIBIABHDQALIAAhAQwCCyAHQQJqIgchBAJAIAAgB00NACABLQAAIQEDQCAEIAVqLQAAIAFGDQEgBEEBaiIEIABJDQALIAAhBAsgACAHayIAIAQgB2siASAAIAFJGyIAQfj///8HTw0DAkACQCAAQQtPBEAgAEEHciIIQQFqEH8hASADIAhB/////wdrNgI0IAMgATYCLCADIAA2AjAMAQsgAyAAOgA3IANBLGohASAARQ0BCyAARQ0AIAEgBSAHaiAA/AoAAAsgACABakEAOgAAIAMsAENBAEgEQCADKAJAGiADKAI4EHILIAkgAygCNDYCACADIAMpAiw3AzggBCAEIAIoAiwgAiwAMyIAIABBAEgbSWohAQwCCyADQUBrQQA2AgAgA0IANwM4IAQhAQsgACAHTQ0CIAAgBGsiACABIARrIgcgACAHSRsiAEH4////B08NAQJAAkAgAEELTwRAIABBB3IiCUEBahB/IQcgAyAJQf////8HazYCNCADIAc2AiwgAyAANgIwDAELIAMgADoANyADQSxqIQcgAEUNAQsgAEUNACAHIAQgBWogAPwKAAALIAAgB2pBADoAACADLABDQQBIBEAgAygCQBogAygCOBByCyADQUBrIAMoAjQ2AgAgAyADKQIsNwM4CyADIANByABqNgJcIANBLGogCiADQcgAaiADQdwAahAZAkAgAygCLCIFQRRqIgAgA0E4akYNACADLABDIQQgBSwAH0EATgRAIARBAE4EQCAAIAMpAzg3AgAgACADQUBrKAIANgIIDAcLIAAgAygCOCADKAI8EJwBDAELIAAgAygCOCADQThqIARBAEgiBRsgAygCPCAEIAUbEJsBCyADLABDQQBODQQgAygCQBogAygCOBByDAQLEAcAC0EIEKgBQfIOEIEBIgBBrNsANgIAIABBuNsAQQEQAAALIAQLIQEgAyADQcgAajYCLCADQThqIAogA0HIAGogA0EsahAZAn8gAygCOCIALAAfQQBIBEAgAEEANgIYIAAoAhQMAQsgAEEAOgAfIABBFGoLQQA6AAALIAMsAFNBAEgEQCADKAJQGiADKAJIEHILIAIoAiwhCCACLQAzIQkLIAEgCCAJQf8BcSAJwEEASCIFGyIASQ0ACwtBACEAQQAhBQJAIAMoAgwgAywAEyIBIAFBAEgbQQVHDQAgAygCCCADQQhqIAFBAEgbQcAMQQUQVQ0AIANBAzoAUyADQQA6AEsgA0HnEC8AADsBSCADQekQLQAAOgBKAn8gA0EUaiEKQQAhCSADQcgAaiIGKAIEIAYsAAsiCCAIQQBIIgQbIgchCCAGKAIAIAYgBBsi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+AEgA0H4AWogBUEASCIEGyADKAL8ASAFIAQbEJsBCyADLACDAkEATg0AIAMoAoACGiADKAL4ARByCyADIAA2AvQBIAMgAEEMajYC8AEgACAAKAIEQQFqNgIEIAMgAykC8AE3AwggAiADQQhqEBggACAAKAIEIgJBAWs2AgQgAg0OIAAgACgCACgCCBEBACAAEHwMDgtBPBB/IgBCADcCECAAQQw2AgwgAEGUFzYCACAAQgA3AgQgAEIANwI0IABCgICA/AM3AiwgAEIANwIYIABCADcCICAAQQA2AiggAyAANgLsASADIABBDGo2AugBIAMgAykC6AE3AxAgAiADQRBqEBgMDQtBPBB/IgBCADcCECAAQSA2AgwgAEGUFzYCACAAQgA3AgQgAEIANwI0IABCgICA/AM3AiwgAEIANwIYIABCADcCICAAQQA2AiggAEEMaiEEAkAgAUUNAAJAAkAgASgCBCIFBEAgASgCACIGDQELIANBADYCgAIgA0IANwP4AQwBCyAFQfj///8HTw0PAkAgBUELTwRAIAVBB3IiB0EBahB/IQEgAyAHQf////8HazYCgAIgAyABNgL4ASADIAU2AvwBDAELIAMgBToAgwIgA0H4AWohAQsgBQRAIAEgBiAF/AoAAAsgASAFakEAOgAAIAMoAvwBIAMtAIMCIgEgAcBBAEgbRQ0AIARB9NwAIANB+AFqEBoLIAMsAIMCQQBODQAgAygCgAIaIAMoAvgBEHILIAMgADYC5AEgAyAENgLgASAAIAAoAgRBAWo2AgQgAyADKQLgATcDGCACIANBGGoQGCAAIAAoAgQiAkEBazYCBCACDQwgACAAKAIAKAIIEQEAIAAQfAwMC0E8EH8iAEIANwIQIABBDTYCDCAAQZQXNgIAIABCADcCBCAAQgA3AjQgAEKAgID8AzcCLCAAQgA3AhggAEIANwIgIABBADYCKCADIAA2AtwBIAMgAEEMajYC2AEgAyADKQLYATcDICACIANBIGoQGAwLC0E8EH8iAEIANwIQIABBDjYCDCAAQZQXNgIAIABCADcCBCAAQgA3AjQgAEKAgID8AzcCLCAAQgA3AhggAEIANwIgIABBADYCKCAAQQxqIQQCQCABRQ0AIAEoAgAiAUEBRg0AIANB+AFqIAEQnwEgBEHc3AAgA0H4AWoQGiADLACDAkEATg0AIAMoAoACGiADKAL4ARByCyADIAA2AtQBIAMgBDYC0AEgACAAKAIEQQFqNgIEIAMgAykC0AE3AyggAiADQShqEBggACAAKAIEIgJBAWs2AgQgAg0KIAAgACgCACgCCBEBACAAEHwMCgtBPBB/IgBCADcCECAAQQ82AgwgAEGUFzYCACAAQgA3AgQgAEIANwI0IABCgICA/AM3AiwgAEIANwIYIABCADcCICAAQQA2AiggAEEMaiEEAkAgAUUNACABKAIARQ0AIARBxNwAIANB+AFqQacPEBsiBRAaIAUsAAtBAEgEQCAFKAIIGiAFKAIAEHILIARB0NwAIANB+AFqQacPQccPIAEtAARB3wFxQdgARhsQGyIBEBogASwAC0EATg0AIAEoAggaIAEoAgAQcgsgAyAANgLMASADIAQ2AsgBIAAgACgCBEEBajYCBCADIAMpAsgBNwMwIAIgA0EwahAYIAAgACgCBCICQQFrNgIEIAINCSAAIAAoAgAoAggRAQAgABB8DAkLQTwQfyIAQgA3AhAgAEEQNgIMIABBlBc2AgAgAEIANwIEIABCADcCNCAAQoCAgPwDNwIsIABCADcCGCAAQgA3AiAgAEEANgIoIABBDGohBAJAIAFFDQACQCABLQAgIgVFDQAgA0EAOgClASADIAU6AKQBIARBqNwAIANB+AFqIANBpAFqEBsiBRAaIAUsAAtBAE4NACAFKAIIGiAFKAIAEHILAkACQCABKAIUIgUEQCABKAIQIgYNAQsgA0EANgKAAiADQgA3A/gBDAELIAVB+P///wdPDQsCQCAFQQtPBEAgBUEHciIHQQFqEH8hASADIAdB/////wdrNgKAAiADIAE2AvgBIAMgBTYC/AEMAQsgAyAFOgCDAiADQfgBaiEBCyAFBEAgASAGIAX8CgAACyABIAVqQQA6AAAgAygC/AEgAy0AgwIiASABwEEASBtFDQAgBEG43AAgA0H4AWoQGgsgAywAgwJBAE4NACADKAKAAhogAygC+AEQcgsgAyAANgLEASADIAQ2AsABIAAgACgCBEEBajYCBCADIAMpAsABNwM4IAIgA0E4ahAYIAAgACgCBCICQQFrNgIEIAINCCAAIAAoAgAoAggRAQAgABB8DAgLQTwQfyIAQgA3AhAgAEERNgIMIABBlBc2AgAgAEIANwIEIABCADcCNCAAQoCAgPwDNwIsIABCADcCGCAAQgA3AiAgAEEANgIoIAMgADYCvAEgAyAAQQxqNgK4ASADIAMpArgBNwNAIAIgA0FAaxAYDAcLQTwQfyIAQgA3AhAgAEEfNgIMIABBlBc2AgAgAEIANwIEIABCADcCNCAAQoCAgPwDNwIsIABCADcCGCAAQgA3AiAgAEEANgIoIABBDGohBAJAIAFFDQAgA0H4AWogASgCABCfASADQejcADYCmAIgA0GkAWogAEEcakHo3AAgA0GYAmoQGQJAIAMoAqQBIgVBFGoiASADQfgBakYNACADLACDAiEGIAUsAB9BAE4EQCAGQQBOBEAgASADKQL4ATcCACABIAMoAoACNgIIDAILIAEgAygC+AEgAygC/AEQnAEMAQsgASADKAL4ASADQfgBaiAGQQBIIgUbIAMoAvwBIAYgBRsQmwELIAMsAIMCQQBODQAgAygCgAIaIAMoAvgBEHILIAMgADYCtAEgAyAENgKwASAAIAAoAgRBAWo2AgQgAyADKQKwATcDSCACIANByABqEBggACAAKAIEIgJBAWs2AgQgAg0GIAAgACgCACgCCBEBACAAEHwMBgtBPBB/IgBCADcCECAAQRI2AgwgAEGUFzYCACAAQgA3AgQgAEIANwI0IABCgICA/AM3AiwgAEIANwIYIABCADcCICAAQQA2AiggAEEMaiEFAkAgAUUNACADQQA6AIACIANC496xm/Stnbf0ADcD+AEgA0EIOgCDAiADQaQBaiABKAIAEJ8BIAMgA0H4AWo2ApQCIANBmAJqIABBHGoiBiADQfgBaiADQZQCahAZAkAgAygCmAIiB0EUaiIEIANBpAFqRg0AIAMsAK8BIQggBywAH0EATgRAIAhBAE4EQCAEIAMpAqQBNwIAIAQgAygCrAE2AggMAgsgBCADKAKkASADKAKoARCcAQwBCyAEIAMoAqQBIANBpAFqIAhBAEgiBxsgAygCqAEgCCAHGxCbAQsgAywArwFBAEgEQCADKAKsARogAygCpAEQcgsgAywAgwJBAEgEQCADKAKAAhogAygC+AEQcgsgA0EQEH8iBDYC+AEgA0KMgICAgIKAgIB/NwL8ASAEQf0JKAAANgAIIARB9QkpAAA3AAAgBEEAOgAMIANBpAFqIAEoAgQQnwEgAyADQfgBajYClAIgA0GYAmogBiADQfgBaiADQZQCahAZAkAgAygCmAIiB0EUaiIEIANBpAFqRg0AIAMsAK8BIQggBywAH0EATgRAIAhBAE4EQCAEIAMpAqQBNwIAIAQgAygCrAE2AggMAgsgBCADKAKkASADKAKoARCcAQwBCyAEIAMoAqQBIANBpAFqIAhBAEgiBxsgAygCqAEgCCAHGxCbAQsgAywArwFBAEgEQCADKAKsARogAygCpAEQcgsgAywAgwJBAEgEQCADKAKAAhogAygC+AEQcgsgA0EQEH8iBDYC+AEgA0KMgICAgIKAgIB/NwL8ASAEQfAJKAAANgAIIARB6AkpAAA3AAAgBEEAOgAMIANBpAFqIAEoAggQnwEgAyADQfgBajYClAIgA0GYAmogBiADQfgBaiADQZQCahAZAkAgAygCmAIiBEEUaiIBIANBpAFqRg0AIAMsAK8BIQYgBCwAH0EATgRAIAZBAE4EQCABIAMpAqQBNwIAIAEgAygCrAE2AggMAgsgASADKAKkASADKAKoARCcAQwBCyABIAMoAqQBIANBpAFqIAZBAEgiBBsgAygCqAEgBiAEGxCbAQsgAywArwFBAEgEQCADKAKsARogAygCpAEQcgsgAywAgwJBAE4NACADKAKAAhogAygC+AEQcgsgAyAANgKgASADIAU2ApwBIAAgACgCBEEBajYCBCADIAMpApwBNwNQIAIgA0HQAGoQGCAAIAAoAgQiAkEBazYCBCACDQUgACAAKAIAKAIIEQEAIAAQfAwFC0E8EH8iAEIANwIQIABBEzYCDCAAQZQXNgIAIABCADcCBCAAQgA3AjQgAEKAgID8AzcCLCAAQgA3AhggAEIANwIgIABBADYCKCADIAA2ApgBIAMgAEEMajYClAEgAyADKQKUATcDWCACIANB2ABqEBgMBAtBPBB/IgBCADcCECAAQRQ2AgwgAEGUFzYCACAAQgA3AgQgAEIANwI0IABCgICA/AM3AiwgAEIANwIYIABCADcCICAAQQA2AiggAyAANgKQASADIABBDGo2AowBIAMgAykCjAE3A2AgAiADQeAAahAYDAMLQTwQfyIAQgA3AhAgAEEVNgIMIABBlBc2AgAgAEIANwIEIABCADcCNCAAQoCAgPwDNwIsIABCADcCGCAAQgA3AiAgAEEANgIoIAMgADYCiAEgAyAA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IQwDQCAGIApBA3QiDWooAgAiASgCACIJQQ1rQQJPBH8gCkEBagVBASEIAkAgASgCJCIFIAEoAigiBEYNACAFIQEDQAJAAkAgASgCACICKAIAQQ9HDQAgAigCKCACKAIkIgJrQQhHDQAgAigCACgCAEEhRg0BCyABQQhqIgEgBEcNAQwCCwsgA0EANgIcIANCADcCFCADQQA2AhAgA0IANwIIA0ACQAJAIAUoAgAiASgCAEEPRw0AIAEoAiggASgCJCIBa0EIRw0AIAEoAgAoAgBBIUcNACADKAIIIgIgAygCDCIGRwRAQTwQfyIBQgA3AhAgASAJNgIMIAFBlBc2AgAgAUIANwIEIAFCADcCGCABQgA3AiAgAUKAgICAgICAwD83AiggAyABNgIEIAMgAUEMajYCACABIANBEGoiBygCADYCOCABIAY2AjQgASACNgIwIAdBADYCACADQgA3AwggA0EUaiADEB0CQCADKAIEIgFFDQAgASABKAIEIgJBAWs2AgQgAg0AIAEgASgCACgCCBEBACABEHwLIAUoAgAoAiQhAQsgAygCGCICIAMoAhwiB0kEQCACIAEoAgA2AgAgAiABKAIEIgE2AgQgAQRAIAEgASgCBEEBajYCBAsgAyACQQhqNgIYDAILIAIgAygCFCIGayICQQN1Ig5BAWoiCEGAgICAAk8NB0H/////ASAHIAZrIgdBAnUiCyAIIAggC0kbIAdB+P///wdPGyIIQYCAgIACTw0IIAhBA3QiBxB/IgsgAmoiCCABKAIANgIAIAggASgCBCIBNgIEIAcgC2ohByAIIAEEfyABIAEoAgRBAWo2AgQgAygCHBogAygCGCAGayICQQN1BSAOC0EDdGshASACBEAgASAGIAL8CgAACyADIAc2AhwgAyAIQQhqIgI2AhggAyABNgIUIAYEQCAGEHILIAMgAjYCGAwBCyADQQhqIAUQHQsgBUEIaiIFIARHDQALAkAgAygCCCICIAMoAgwiBEYNAEE8EH8iAUIANwIQIAEgCTYCDCABQZQXNgIAIAFCADcCBCABQgA3AhggAUIANwIgIAFCgICAgICAgMA/NwIoIAMgATYCBCADIAFBDGo2AgAgASADKAIQNgI4IAEgBDYCNCABIAI2AjAgA0EANgIQIANCADcDCCADQRRqIAMQHSADKAIEIgFFDQAg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ASwAH0EASARAIAEoAhwaIAEoAhQQcgsgASwAE0EASARAIAEoAhAaIAEoAggQcgsgARByIAIiAQ0ACwsgACgCACEBIABBADYCACABBEAgACgCBBogARByCwuNAgEGfyAAKAIEIgIgACgCCCIDSQRAIAIgASgCADYCACACIAEoAgQ2AgQgAUIANwIAIAAgAkEIajYCBA8LAkAgAiAAKAIAIgRrIgVBA3UiB0EBaiICQYCAgIACSQRAQf////8BIAMgBGsiBkECdSIDIAIgAiADSRsgBkH4////B08bIgMEfyADQYCAgIACTw0CIANBA3QQfwVBAAsiBiAFaiICIAEoAgA2AgAgAiABKAIENgIEIAFCADcCACACIAdBA3RrIQEgBQRAIAEgBCAF/AoAAAsgACAGIANBA3RqNgIIIAAgAkEIaiICNgIEIAAgATYCACAEBEAgBBByCyAAIAI2AgQPCxATAAsQFAALzgEBA38jAEEQayICJAAgABAQAkAgASgCACIDRQ0AIAAoAgggACgCDCIARg0AIABBCGsoAgAhBCABKAIEIgAEQCAAIAAoAgRBAWo2AgQLIAIgADYCDCACIAM2AgggBEEkaiACQQhqEB0gAigCDCIARQ0AIAAgACgCBCIDQQFrNgIEIAMNACAAIAAoAgAoAggRAQAgABB8CwJAIAEoAgQiAUUNACABIAEoAgQiAEEBazYCBCAADQAgASABKAIAKAIIEQEAIAEQfAsgAkEQaiQAC90FAQd/IwBBMGsiASQAIAAoAgAiAygCACIEIAMoAgQiAkcEQCAEIQMCQAJAA0AgAygCABARBEAgAiADQQhqIgNHDQEMAgsLQTwQfyICQgA3AhAgAkEBNgIMIAJBlBc2AgAgAkIANwIEIAJCADcCNCACQoCAgPwDNwIsIAJCADcCGCACQgA3AiAgAkEANgIoIAEgAjYCHCABIAJBDGo2AhggAUGqCi0AADoAECABQQU6ABcgAUGmCigAADYCDCABQQA6ABEgAUEAOgAEIAFB9OTVqwY2AgAgAUEEOgALIAEgAUEMajYCJCABQShqIAJBHGogAUEMaiABQSRqEBkCQCABKAIoIgNBFGoiBCABRg0AIAMsAB9BAE4EQCAEIAEpAgA3AgAgBCABKAIINgIIDAELIAQgAUEEEJsBIAEsAAtBAE4NACABKAIIGiABKAIAEHILIAEsABdBAEgEQCABKAIUGiABKAIMEHILIAAoAgAhBSACKAIwIgcEQCAHIgMgAigCNCIERwRAA0ACQCAEQQRrKAIAIgNFDQAgAyADKAIEIgZBAWs2AgQgBg0AIAMgAygCACgCCBEBACADEHwLIAcgBEEIayIERw0ACyACKAIwIQMLIAIgBzYCNCACKAI4GiADEHIgAkEANgI4IAJCADcCMAsgAiAFKAIANgIwIAIgBSgCBDYCNCACIAUoAgg2AjggBUEANgIIIAVCADcCACAAKAIEIAFBGGoQHSABKAIcIgRFDQEgBCAEKAIEIgNBAWs2AgQgAw0BIAQgBCgCACgCCBEBACAEEHwMAQsDQCAAKAIEIAQQHSAEQQhqIgQgAkcNAAsLIAAoAgAiBigCACIAIAYoAgQiBEcEQANAAkAgBEEEaygCACIDRQ0AIAMgAygCBCICQQFrNgIEIAINACADIAMoAgAoAggRAQAgAxB8CyAAIARBCGsiBEcNAAsLIAYgADYCBAsgAUEwaiQACyAAQY/cACwAAEEASARAQYzcACgCABpBhNwAKAIAEHILCyAAQZvcACwAAEEASARAQZjcACgCABpBkNwAKAIAEHILCyAAQafcACwAAEEASARAQaTcACgCABpBnNwAKAIAEHILCyAAQbPcACwAAEEASARAQbDcACgCABpBqNwAKAIAEHILCyAAQcPcACwAAEEASARAQcDcACgCABpBuNwAKAIAEHILCyAAQc/cACwAAEEASARAQczcACgCABpBxNwAKAIAEHILCyAAQdvcACwAAEEASARAQdjcACgCABpB0NwAKAIAEHILCyAAQefcACwAAEEASARAQeTcACgCABpB3NwAKAIAEHILCyAAQfPcACwAAEEASARAQfDcACgCABpB6NwAKAIAEHILCyAAQf/cACwAAEEASARAQfzcACgCABpB9NwAKAIAEHILCwwAIABBlBc2AgAgAAsOACAAQZQXNgIAIAAQcgusAQEFfyMAQRBrIgQkACAAQQxqIgEoAiQiAgRAIAIiACABKAIoIgNHBEADQAJAIANBBGsoAgAiAEUNACAAIAAoAgQiBUEBazYCBCAFDQAgACAAKAIAKAIIEQEAIAAQfAsgAiADQQhrIgNHDQALIAEoAiQhAAsgASACNgIoIAEoAiwaIAAQcgsgAUEQ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ACABGyEADAELCyADQRBqJAAgBUEQaiQAIAALBQAQdgALDQAgACgCACABKAIASQsEACAACyoBAX8CQCAAQQhqIgEoAgAEQCABEH1Bf0cNAQsgACAAKAIAKAIQEQEACwsTACAAIAAoAgBBAWsiADYCACAACwQAQQALPQECf0EBIAAgAEEBTRshAQNAAkAgARBxIgINAEGw4gAoAgAiAEUNACAAEQkADAELCyACIgBFBEAQeQsgAAsNACAAQdjZADYCACAAC10BA38gABCAASIAQcjaADYCACAAQQRqIQQgARBhIgNBDWoQfyICQQA2AgggAiADNgIEIAIgAzYCACACQQxqIQIgA0EBaiIDBEAgAiABIAP8CgAACyAEIAI2AgAgAAsKACAALQALQQd2CxUAIAAQggEEQCAAKAIEDwsgABCHAQsbAQF/QQohASAAEIIBBH8gABCIAUEBawUgAQsLEgAgABCCAQRAIAAoAgAPCyAAC6gCAQN/IwBBIGsiCCQAQff///8HIgkgAUF/c2ogAk8EQCAAEIUBIQogAUHz////A0kEQCAIIAFBAXQ2AhwgCCABIAJqNgIQIAhBEGogCEEcahCMASgCABCNAUEBaiEJCyAIQRxqIAhBGGogABCOASgCABCPASAIQRBqIAkQkAEgCCgCECEJIAgoAhQaIAQEQCAJIAogBBCRAQsgBgRAIAQgCWogByAGEJEBCyADIAQgBWoiB2shAiADIAdHBEAgBCAJaiAGaiAEIApqIAVqIAIQkQELIAFBCkcEQCAKEHILIAAgCRCSASAAIAgoAhQQkwEgACAEIAZqIAJqIgQQlAEgCEEAOgAPIAQgCWogCEEPahCLASAIQRxqEJoBIAhBIGokAA8LEJUBAAsLACAALQALQf8AcQsOACAAKAIIQf////8HcQsZAAJAIAJFDQAgAkUNACAAIAEgAvwKAAALCxkAIAAQggEEQCAAIAEQlAEPCyAAIAEQlwELDAAgACABLQAAOgAACyMBAn8jAEEQayICJAAgACABEHohAyACQRBqJAAgASAAIAMbCyQAIABBC08EfyAAQQhqQXhxIgAgAEEBayIAIABBC0YbBUEKCwsLACAAIAE2AgAgAAsKACAAIAEQjgEaCxgBAX8gARB/IQIgACABNgIEIAAgAjYCAAsLACAAIAEgAhCJAQsJACAAIAE2AgALEAAgACABQYCAgIB4cjYCCAsJACAAIAE2AgQLBQAQeQALBwAgAEELSQsNACAAIAFB/wBxOgALC64CAQZ/IAFB9////wdNBEAgABCEASABSQRAIAEQjQEhAiMAQRBrIgEkACABQQxqIAFBCGogABCOASgCABCPASAAEIQBIQQgABCDASEGAkACfyACEJYBIgcEQEEBIQQgAkEBaiEFIAAhAiAAKAIADAELIAJBAWohAwJAIAIgBEsEQCABIAMQkAEgASgCBCEFIAEoAgAhAgwBCyABIAMQkAEgASgCBCEDIAAQhAEhBCABKAIEIQUgASgCACECIANBAWsgBE0NACACEHIMAgsgABCCASEEIAAQhQELIQMgAiADIAAQgwFBAWoQkQEgBARAIAMQcgsgB0UEQCAAIAUQkwEgACAGEJQBIAAgAhCSAQwBCyAAIAYQlwELIAFBDGoQmgEgAUEQaiQACw8LEJUBAAt9AQN/IwBBEGsiBSQAAkAgAiAAEIQBIgQgABCDASIDa00EQCACRQ0BIAAQhQEiBCADaiABIAIQkQEgACACIANqIgIQigEgBUEAOgAPIAIgBGogBUEPahCLAQwBCyAAIAQgAiAEayADaiADIANBACACIAEQhgELIAVBEGokAAsLACAAKAIAEIMBGgt2AQN/IwBBEGsiBCQAIAAQiAEhAyAAKAIEIQUCQCACIANJBEAgACgCACEDIAAgAhCUASADIAEgAhCRASAEQQA6AA8gAiADaiAEQQ9qEIsBDAELIAAgA0EBayACIANrQQFqIAVBACAFIAIgARCGAQsgBEEQaiQAC2IBAn8jAEEQayIDJAAgABCHASEEAkAgAkEKTQRAIAAgAhCXASAAIAEgAhCRASADQQA6AA8gACACaiADQQ9qEIsBDAELIABBCiACQQprIARBACAEIAIgARCGAQsgA0EQaiQAC4IDAQZ/IwBBEGsiBCQAIAQgAToADwJAAkACfyAAEIIBIgNFBEBBCiECIAAQhwEMAQsgABCIAUEBayECIAAoAgQLIgEgAkYEQCMAQRBrIgUkACAFQQxqIAVBCGogABCOASgCABCPASMAQRBrIgMkAAJAIAJB9////wdHBEAgABCFASEGIANBBGogAkHz////A0kEfyADIAJBAXQ2AgwgAyACQQFqNgIEIANBBGogA0EMahCMASgCABCNAUEBagVB9////wcLEJABIAMoAgQhByADKAIIGiACBEAgByAGIAIQkQELIAJBCkcEQCAGEHILIAAgBxCSASAAIAMoAggQkwEgA0EQaiQADAELEJUBAAsgACACEJQBIAVBDGoQmgEgBUEQaiQAIAAQhQEaDAELIAAQhQEaIAMNACAAIgIgAUEBahCXAQwBCyAAKAIAIQIgACABQQFqEJQBCyABIAJqIgAgBEEPahCLASAEQQA6AA4gAEEBaiAEQQ5qEIsBIARBEGokAAsNACAAIAEgARBhEJkBC6wEAQZ/IwBBIGsiBCQAIARBDGoiBQJ/IARBIGoiAyAEQRVqIgJrIgZBCUwEQEE9IAZBICABQQFyZ2tB0QlsQQx1IgcgASAHQQJ0QfDUAGooAgBPakgNARoLAn8gAUG/hD1NBEAgAUGPzgBNBEAgAUHjAE0EQCABQQlNBEAgAiABEKABDAQLIAIgARChAQwDCyABQecHTQRAIAIgAUHkAG4iAhCgASABIAJB5ABsaxChAQwDCyACIAEQogEMAgsgAUGfjQZNBEAgAiABQZDOAG4iAhCgASABIAJBkM4AbGsQogEMAgsgAiABEKMBDAELIAFB/8HXL00EQCABQf+s4gRNBEAgAiABQcCEPW4iAhCgASABIAJBwIQ9bGsQowEMAgsgAiABEKQBDAELIAFB/5Pr3ANNBEAgAiABQYDC1y9uIgIQoAEgASACQYDC1y9saxCkAQwBCyACIAFBgMLXL24iAhChASABIAJBgMLXL2xrEKQBCyEDQQALNgIEIAUgAzYCACAEKAIMIQYjAEEQayICJAACQCAGIARBFWoiA2siBUH3////B00EQAJAIAUQlgEEQCAAIAUQlwEgACEBDAELIAJBCGogBRCNAUEBahCQASACKAIMGiAAIAIoAggiARCSASAAIAIoAgwQkwEgACAFEJQBCyABIAMgBiADayIDEJEBIAJBADoAByABIANqIAJBB2oQiwEgAkEQaiQADAELEJUBAAsgBEEgaiQACxEAIAAgAUEwajoAACAAQQFqC+sBAQV/IwBBEGsiBCQAIwBBIGsiAiQAIwBBEGsiAyQAIAMgAUEBdEGg1QBqIgEiBjYCDCADIAFBAmo2AgggAkEYaiADQQxqIANBCGoQpwEgA0EQaiQAIAIoAhghBSACKAIcIQMjAEEQayIBJAAgASADNgIMIAAgBSADIAVrIgMQiQEgASAAIANqNgIIIAJBEGogAUEMaiABQQhqEKYBIAFBEGokACACIAYgAigCEBClATYCDCACIAAgAigCFBClATYCCCAEQQhqIAJBDGogAkEIahCmASACQSBqJAAgBCgCDCEAIARBEGokACAACxsAIAAgAUHkAG4iABChASABIABB5ABsaxChAQsdACAAIAFBkM4AbiIAEKEBIAEgAEGQzgBsaxCiAQsdACAAIAFBwIQ9biIAEKEBIAEgAEHAhD1saxCjAQsKACAAIAEgAGtqCwsAIAAgASACEKcBCxYAIAAgASgCADYCACAAIAIoAgA2AgQLDgAgAEHQAGoQcUHQAGoLdAEBfyACRQRAIAAoAgQgASgCBEYPCyAAIAFGBEBBAQ8LIAEoAgQiAi0AACEBAkAgACgCBCIDLQAAIgBFDQAgACABRw0AA0AgAi0AASEBIAMtAAEiAEUNASACQQFqIQIgA0EBaiEDIAAgAUYNAAsLIAAgAUYLtQUBBn8jAEHQAGsiBCQAAkACf0EBIAAgAUEAEKkBDQAaQQAgAUUNABojAEEQayIFJAAgBUEEaiIDIAEoAgAiBkEIaygCACIHNgIIIAMgASAHajYCACADIAZBBGsoAgA2AgQgBSgCCCIGQZjXAEEAEKkBIQMgBSgCBCEHAkAgAwRAIAUoAgwhASMAQUBqIgMkACADQUBrJABBACAHIAEbIQMMAQsjAEFAaiIDJAAgASAHTgRAIANBHGoiCEIANwIAIANCADcCJCADQgA3AiwgA0IANwIUIANBADYCECADQZjXADYCDCADIAY2AgQgA0EANgI8IANCgYCAgICAgIABNwI0IAMgATYCCCAGIANBBGogByAHQQFBACAGKAIAKAIUEQoAIAFBACAIKAIAGyEICyADQUBrJAAgCCIDDQAjAEFAaiIDJAAgA0EANgIQIANB6NYANgIMIAMgATYCCCADQZjXADYCBEEAIQEgA0EUakEAQSf8CwAgA0EANgI8IANBAToAOyAGIANBBGogB0EBQQAgBigCACgCGBEIAAJAAkACQCADKAIoDgIAAQILIAMoAhhBACADKAIkQQFGG0EAIAMoAiBBAUYbQQAgAygCLEEBRhshAQwBCyADKAIcQQFHBEAgAygCLA0BIAMoAiBBAUcNASAD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dW50AGJhc2Vmb250AERvY3VtZW50AGltcG9ydGFudABkZWZhdWx0AHRpZ2h0AHJpZ2h0AEhpZ2hsaWdodABsZWZ0AGZyYW1lc2V0AGZpZWxkc2V0AGR0AFx0AGFkZHJlc3MAaHR0cHMAZGV0YWlscwBFbXBoYXNpcwBub2ZyYW1lcwAlczolZDogJXMAdHIAdmVjdG9yAGRpcgBocgBmb290ZXIAY2VudGVyAFNwb2lsZXIAaGVhZGVyAGZlbmNlQ2hhcgBccgBvcHRncm91cABjb2xncm91cABmdHAAL3NyYy9jcHAvd2FzbS9BU1RTZXJpYWxpemVyLmNwcAAvZW1zZGsvZW1zY3JpcHRlbi9zeXN0ZW0vbGliL2xpYmN4eGFiaS9zcmMvcHJpdmF0ZV90eXBlaW5mby5jcHAAdGlwAHZpZGVvAFZpZGVvAGNhdXRpb24Ab3B0aW9uAHN0ZDo6ZXhjZXB0aW9uAGZpZ2NhcHRpb24AQWRtb25pdGlvbgBzZWN0aW9uAG1haW4AYWxpZ24AbmFuAFxuAGZvcm0AbWVudWl0ZW0ATGlzdEl0ZW0AcGFyYW0AdWwAdXJsAGNvbABodG1sAFRhYmxlSGVhZGVyQ2VsbABUYWJsZUNlbGwAbGV2ZWwAZGwAaXNUYXNrAGxpbmsATGluawBDb2RlQmxvY2sAdHJhY2sAU29mdEJyZWFrAExpbmVCcmVhawBUaGVtYXRpY0JyZWFrAGxpAGJhZF9hcnJheV9uZXdfbGVuZ3RoAFBhcmFncmFwaABTdHJpa2V0aHJvdWdoAHNlYXJjaABkaWFsb2cAU3Ryb25nAGJhc2ljX3N0cmluZwBub2RlVHlwZVRvU3RyaW5nAHdhcm5pbmcASGVhZGluZwBpbmYAXGYAdHJ1ZQBibG9ja3F1b3RlAEJsb2NrcXVvdGUAbm90ZQBmYWxzZQBiYXNlAGZpZ3VyZQBhZG1vbml0aW9uVHlwZQBVbmRlcmxpbmUATGF0ZXhNYXRoSW5saW5lAEJsYW5rTGluZQBpZnJhbWUAdGl0bGUAYXJ0aWNsZQB0YWJsZQBUYWJsZQBJbWFnZQBDb2RlAGFzaWRlAHRkAGxlZ2VuZAB0YXNrQ2hlY2tlZABkZAB0aGVhZABUYWJsZUhlYWQAc3JjAHN0ZDo6YmFkX2FsbG9jAFxiACInPTw+YAAtXwAuLStfAFxcACh7WwAsImNoaWxkcmVuIjpbAE5BTgBJTkYAY2F0Y2hpbmcgYSBjbGFzcyB3aXRob3V0IGFuIG9iamVjdD8AXV0+AC0tPgBtYWlsdG86ACl9XS4hPyw7OgAsImNvbnRlbnQiOgBoNgBoNQBoNABoMwBoMgBoMQBodHRwOi8vAFRvbyBtYW55IGxpbmsgcmVmZXJlbmNlIGRlZmluaXRpb24gaW5zdGFudGlhdGlvbnMuAFVuc3VwcG9ydGVkIGFiaV92ZXJzaW9uLgBBYm9ydGVkIGZyb20gdGV4dCgpIGNhbGxiYWNrLgBBYm9ydGVkIGZyb20gZW50ZXJfc3BhbigpIGNhbGxiYWNrLgBBYm9ydGVkIGZyb20gbGVhdmVfc3BhbigpIGNhbGxiYWNrLgBBYm9ydGVkIGZyb20gZW50ZXJfYmxvY2soKSBjYWxsYmFjay4AQWJvcnRlZCBmcm9tIGxlYXZlX2Jsb2NrKCkgY2FsbGJhY2suAG1hbGxvYygpIGZhaWxlZC4AcmVhbGxvYygpIGZhaWxlZC4AQDouAC4hIyQlJicqKy89P15fYHt8fX4tAF8uOi0AKy0ALi1fKwAtXyoAKG51bGwpAFN1cHByZXNzaW5nIHRvbyBzcGFyc2UgdGFibGUgKHNlZSBodHRwczovL2dpdGh1Yi5jb20vbWl0eS9tZDRjL2lzc3Vlcy8zNDUpAC5fPSgpAC4rLV9+JSgpAGZhbHNlICYmICJ1bmhhbmRsZWQgTm9kZVR5cGUgaW4gbm9kZVR5cGVUb1N0cmluZyIAXCIAeyJ0eXBlIjoiAFtdIQB4WCAACgALBQAARQcAAKEEAAD2BgAAmAcAABUHAABrBwAAbwUAAE8HAADoBwAAMwgAAC0IAAC3BwAApgQAALQEAACoBgAA+wYAAB8HAAAnCAAAXQgAADIEAACLBAAAxwYAANcGAADyBwAAPAQAAKoFAADGBAAA0gQAADIFAAALBwAAAggAAHUGAABGBgBBkBcLfqgLAAATAAAAFAAAABUAAAAWAAAAFwAAAPgrAAC0CwAANCoAAE5TdDNfXzIyMF9fc2hhcmVkX3B0cl9lbXBsYWNlSU44TWFya2Rvd24xNU1hcmtkb3duQVNUTm9kZUVOU185YWxsb2NhdG9ySVMyX0VFRUUAPAUAAKMFAAAsBQBBsBgLEsIHAAA8BgAAFAUAAJAHAABMBgBB0BgLZsAMAADgDAAAEA0AAEANAAC4DAAAgA0AALgMAADADQAAIA4AALgMAAC4DAAAMA4AAFAOAABwDgAAkA4AALAOAAC4DAAAuAwAANAOAADwDgAAQA8AAFAPAAC4DAAAuAwAALgMAAC4DABBwBkLFVkFAAAHAAAAGQgAAAcAAAA4CAAABQBB4BkLHc0HAAAEAAAAAgUAAAgAAACsBwAACgAAAC0EAAAEAEGQGgsdbQYAAAcAAACjBQAABgAAAL4GAAADAAAAzwUAAAgAQcAaCzVUCAAAAgAAAGcFAAAHAAAAZAcAAAYAAACVBQAAAwAAAJQEAAADAAAA5wYAAAIAAABTBQAAAgBBgBsLNUoFAAAIAAAAagYAAAoAAADSBwAABgAAAJwFAAAGAAAAmgYAAAQAAAANCAAABQAAAEEFAAAIAEHAGwtNAgkAAAIAAAD/CAAAAgAAAPwIAAACAAAA+QgAAAIAAAD2CAAAAgAAAPMIAAACAAAAWAgAAAQAAACyBQAABgAAAJkFAAACAAAAwgYAAAQAQaAcCwUMCAAABgBBsBwLFUEIAAAGAAAALQcAAAIAAADxBgAABABB0BwLFYgGAAAEAAAAnAQAAAQAAACfBgAACABB8BwLDZgEAAADAAAAeAUAAAgAQZAdCxW/BgAAAgAAAMYFAAAIAAAAVAYAAAYAQbAdCw0+BgAAAQAAALEGAAAFAEHQHQsVXQcAAAYAAACABgAABwAAACQEAAAHAEHwHQtFIQgAAAUAAAAsBAAABQAAAD4IAAACAAAA3AQAAAUAAABCBwAAAgAAAFcIAAAFAAAAEwgAAAUAAACLBQAAAgAAAAUHAAAFAEHAHgsFtwYAAAIAQdAeCwVABgAABQBB4B4LlxMgAAAAoAAAAIAWAAAAIABACiAAgC8gAABfIAAAADAAAEEAAEBaAACAtQAAAMAAAEDWAACA2AAAQN4AAIAAAQBALgEAgDIBAEA2AQCAOQEAQEcBAIBKAQBAdgEAgHgBAAB5AQBAfQEAgH8BAACBAQAAggEAAIQBAACGAQAAhwEAAIkBAACKAQAAiwEAAI4BAACPAQAAkAEAAJEBAACTAQAAlAEAAJYBAACXAQAAmAEAAJwBAACdAQAAnwEAAKABAECkAQCApgEAAKcBAACpAQAArAEAAK4BAACvAQAAsQEAALIBAACzAQAAtQEAALcBAAC4AQAAvAEAAMQBAADFAQAAxwEAAMgBAADKAQAAywEAQNsBAIDeAQBA7gEAgPEBAADyAQAA9AEAAPYBAAD3AQAA+AEAQB4CAIAgAgAAIgIAQDICAIA6AgAAOwIAAD0CAAA+AgAAQQIAAEMCAABEAgAARQIAAEYCAEBOAgCARQMAAHADAAByAwAAdgMAAH8DAACGAwAAiAMAQIoDAICMAwAAjgMAAI8DAACRAwBAoQMAgKMDAECrAwCAwgMAAM8DAADQAwAA0QMAANUDAADWAwAA2AMAQO4DAIDwAwAA8QMAAPQDAAD1AwAA9wMAAPkDAAD6AwAA/QMAQP8DAIAABABADwQAgBAEAEAvBACAYAQAQIAEAICKBABAvgQAgMAEAADBBABAzQQAgNAEAEAuBQCAMQUAQFYFAICgEABAxRAAgMcQAADNEAAA+BMAQP0TAICAHAAAgRwAAIIcAACDHAAAhBwAAIUcAACGHAAAhxwAAIgcAACJHAAAkBwAQLocAIC9HABAvxwAgAAeAECUHgCAmx4AAKAeAED+HgCACB8AQA8fAIAYHwBAHR8AgCgfAEAvHwCAOB8AQD8fAIBIHwBATR8AgFkfAABbHwAAXR8AAF8fAABoHwBAbx8AgLgfAAC5HwAAuh8AALsfAAC+HwAAyB8AQMsfAIDYHwAA2R8AANofAADbHwAA6B8AAOkfAADqHwAA6x8AAOwfAAD4HwAA+R8AAPofAAD7HwAAJiEAACohAAArIQAAMiEAAGAhAEBvIQCAgyEAALYkAEDPJACAACwAQC8sAIBgLAAAYiwAAGMsAABkLAAAZywAQGssAIBtLAAAbiwAAG8sAABwLAAAciwAAHUsAAB+LAAAfywAAIAsAEDiLACA6ywAAO0sAADyLAAAQKYAQGymAICApgBAmqYAgCKnAEAupwCAMqcAQG6nAIB5pwAAe6cAAH2nAAB+pwBAhqcAgIunAACNpwAAkKcAAJKnAACWpwBAqKcAgKqnAACrpwAArKcAAK2nAACupwAAsKcAALGnAACypwAAs6cAALSnAEDCpwCAxKcAAMWnAADGpwAAx6cAAMmnAADLpwAAzKcAQNqnAIDcpwAA3acAAOKnAAD1pwAAbKsAAG2rAABwqwBAv6sAgCH/AEA6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\")}function getBinarySync(file){if(ArrayBuffer.isView(file)){return file}if(file==wasmBinaryFile&&wasmBinary){return new Uint8Array(wasmBinary)}if(readBinary){return readBinary(file)}throw\"both async and sync fetching of the wasm failed\"}async function getWasmBinary(binaryFile){return getBinarySync(binaryFile)}async function instantiateArrayBuffer(binaryFile,imports){try{var binary=await getWasmBinary(binaryFile);var instance=await WebAssembly.instantiate(binary,imports);return instance}catch(reason){err(`failed to asynchronously prepare wasm: ${reason}`);abort(reason)}}async function instantiateAsync(binary,binaryFile,imports){return instantiateArrayBuffer(binaryFile,imports)}function getWasmImports(){return{env:wasmImports,wasi_snapshot_preview1:wasmImports}}async function createWasm(){function receiveInstance(instance,module){wasmExports=instance.exports;wasmMemory=wasmExports[\"memory\"];updateMemoryViews();assignWasmExports(wasmExports);removeRunDependency(\"wasm-instantiate\");return wasmExports}addRunDependency(\"wasm-instantiate\");function receiveInstantiationResult(result){return receiveInstance(result[\"instance\"])}var info=getWasmImports();if(Module[\"instantiateWasm\"]){return new Promise((resolve,reject)=>{Module[\"instantiateWasm\"](info,(mod,inst)=>{resolve(receiveInstance(mod,inst))})})}wasmBinaryFile??=findWasmBinary();var result=await instantiateAsync(wasmBinary,wasmBinaryFile,info);var exports=receiveInstantiationResult(result);return exports}class ExitStatus{name=\"ExitStatus\";constructor(status){this.message=`Program terminated with exit(${status})`;this.status=status}}var callRuntimeCallbacks=callbacks=>{while(callbacks.length>0){callbacks.shift()(Module)}};var onPostRuns=[];var addOnPostRun=cb=>onPostRuns.push(cb);var onPreRuns=[];var addOnPreRun=cb=>onPreRuns.push(cb);var base64Decode=b64=>{var b1,b2,i=0,j=0,bLength=b64.length;var output=new Uint8Array((bLength*3>>2)-(b64[bLength-2]==\"=\")-(b64[bLength-1]==\"=\"));for(;i>4;output[j+1]=b1<<4|b2>>2;output[j+2]=b2<<6|base64ReverseLookup[b64.charCodeAt(i+3)]}return output};var noExitRuntime=true;var stackRestore=val=>__emscripten_stack_restore(val);var stackSave=()=>_emscripten_stack_get_current();var UTF8Decoder=typeof TextDecoder!=\"undefined\"?new TextDecoder:undefined;var UTF8ArrayToString=(heapOrArray,idx=0,maxBytesToRead=NaN)=>{var endIdx=idx+maxBytesToRead;var endPtr=idx;while(heapOrArray[endPtr]&&!(endPtr>=endIdx))++endPtr;if(endPtr-idx>16&&heapOrArray.buffer&&UTF8Decoder){return UTF8Decoder.decode(heapOrArray.subarray(idx,endPtr))}var str=\"\";while(idx>10,56320|ch&1023)}}return str};var UTF8ToString=(ptr,maxBytesToRead)=>ptr?UTF8ArrayToString(HEAPU8,ptr,maxBytesToRead):\"\";var ___assert_fail=(condition,filename,line,func)=>abort(`Assertion failed: ${UTF8ToString(condition)}, at: `+[filename?UTF8ToString(filename):\"unknown filename\",line,func?UTF8ToString(func):\"unknown function\"]);class ExceptionInfo{constructor(excPtr){this.excPtr=excPtr;this.ptr=excPtr-24}set_type(type){HEAPU32[this.ptr+4>>2]=type}get_type(){return HEAPU32[this.ptr+4>>2]}set_destructor(destructor){HEAPU32[this.ptr+8>>2]=destructor}get_destructor(){return HEAPU32[this.ptr+8>>2]}set_caught(caught){caught=caught?1:0;HEAP8[this.ptr+12]=caught}get_caught(){return HEAP8[this.ptr+12]!=0}set_rethrown(rethrown){rethrown=rethrown?1:0;HEAP8[this.ptr+13]=rethrown}get_rethrown(){return HEAP8[this.ptr+13]!=0}init(type,destructor){this.set_adjusted_ptr(0);this.set_type(type);this.set_destructor(destructor)}set_adjusted_ptr(adjustedPtr){HEAPU32[this.ptr+16>>2]=adjustedPtr}get_adjusted_ptr(){return HEAPU32[this.ptr+16>>2]}}var exceptionLast=0;var uncaughtExceptionCount=0;var ___cxa_throw=(ptr,type,destructor)=>{var info=new ExceptionInfo(ptr);info.init(type,destructor);exceptionLast=ptr;uncaughtExceptionCount++;throw exceptionLast};var __abort_js=()=>abort(\"\");var getHeapMax=()=>536870912;var alignMemory=(size,alignment)=>Math.ceil(size/alignment)*alignment;var growMemory=size=>{var b=wasmMemory.buffer;var pages=(size-b.byteLength+65535)/65536|0;try{wasmMemory.grow(pages);updateMemoryViews();return 1}catch(e){}};var _emscripten_resize_heap=requestedSize=>{var oldSize=HEAPU8.length;requestedSize>>>=0;var maxHeapSize=getHeapMax();if(requestedSize>maxHeapSize){return false}for(var cutDown=1;cutDown<=4;cutDown*=2){var overGrownHeapSize=oldSize*(1+.2/cutDown);overGrownHeapSize=Math.min(overGrownHeapSize,requestedSize+100663296);var newSize=Math.min(maxHeapSize,alignMemory(Math.max(requestedSize,overGrownHeapSize),65536));var replacement=growMemory(newSize);if(replacement){return true}}return false};var getCFunc=ident=>{var func=Module[\"_\"+ident];return func};var writeArrayToMemory=(array,buffer)=>{HEAP8.set(array,buffer)};var lengthBytesUTF8=str=>{var len=0;for(var i=0;i=55296&&c<=57343){len+=4;++i}else{len+=3}}return len};var stringToUTF8Array=(str,heap,outIdx,maxBytesToWrite)=>{if(!(maxBytesToWrite>0))return 0;var startIdx=outIdx;var endIdx=outIdx+maxBytesToWrite-1;for(var i=0;i=endIdx)break;heap[outIdx++]=u}else if(u<=2047){if(outIdx+1>=endIdx)break;heap[outIdx++]=192|u>>6;heap[outIdx++]=128|u&63}else if(u<=65535){if(outIdx+2>=endIdx)break;heap[outIdx++]=224|u>>12;heap[outIdx++]=128|u>>6&63;heap[outIdx++]=128|u&63}else{if(outIdx+3>=endIdx)break;heap[outIdx++]=240|u>>18;heap[outIdx++]=128|u>>12&63;heap[outIdx++]=128|u>>6&63;heap[outIdx++]=128|u&63;i++}}heap[outIdx]=0;return outIdx-startIdx};var stringToUTF8=(str,outPtr,maxBytesToWrite)=>stringToUTF8Array(str,HEAPU8,outPtr,maxBytesToWrite);var stackAlloc=sz=>__emscripten_stack_alloc(sz);var stringToUTF8OnStack=str=>{var size=lengthBytesUTF8(str)+1;var ret=stackAlloc(size);stringToUTF8(str,ret,size);return ret};var ccall=(ident,returnType,argTypes,args,opts)=>{var toC={string:str=>{var ret=0;if(str!==null&&str!==undefined&&str!==0){ret=stringToUTF8OnStack(str)}return ret},array:arr=>{var ret=stackAlloc(arr.length);writeArrayToMemory(arr,ret);return ret}};function convertReturnValue(ret){if(returnType===\"string\"){return UTF8ToString(ret)}if(returnType===\"boolean\")return Boolean(ret);return ret}var func=getCFunc(ident);var cArgs=[];var stack=0;if(args){for(var i=0;i{var numericArgs=!argTypes||argTypes.every(type=>type===\"number\"||type===\"boolean\");var numericRet=returnType!==\"string\";if(numericRet&&numericArgs&&!opts){return getCFunc(ident)}return(...args)=>ccall(ident,returnType,argTypes,args,opts)};for(var base64ReverseLookup=new Uint8Array(123),i=25;i>=0;--i){base64ReverseLookup[48+i]=52+i;base64ReverseLookup[65+i]=i;base64ReverseLookup[97+i]=26+i}base64ReverseLookup[43]=62;base64ReverseLookup[47]=63;{if(Module[\"noExitRuntime\"])noExitRuntime=Module[\"noExitRuntime\"];if(Module[\"print\"])out=Module[\"print\"];if(Module[\"printErr\"])err=Module[\"printErr\"];if(Module[\"wasmBinary\"])wasmBinary=Module[\"wasmBinary\"];if(Module[\"arguments\"])arguments_=Module[\"arguments\"];if(Module[\"thisProgram\"])thisProgram=Module[\"thisProgram\"]}Module[\"ccall\"]=ccall;Module[\"cwrap\"]=cwrap;Module[\"UTF8ToString\"]=UTF8ToString;var _parseMarkdown,__emscripten_stack_restore,__emscripten_stack_alloc,_emscripten_stack_get_current;function assignWasmExports(wasmExports){Module[\"_parseMarkdown\"]=_parseMarkdown=wasmExports[\"parseMarkdown\"];__emscripten_stack_restore=wasmExports[\"_emscripten_stack_restore\"];__emscripten_stack_alloc=wasmExports[\"_emscripten_stack_alloc\"];_emscripten_stack_get_current=wasmExports[\"emscripten_stack_get_current\"]}var wasmImports={__assert_fail:___assert_fail,__cxa_throw:___cxa_throw,_abort_js:__abort_js,emscripten_resize_heap:_emscripten_resize_heap};var wasmExports=await createWasm();function run(){if(runDependencies>0){dependenciesFulfilled=run;return}preRun();if(runDependencies>0){dependenciesFulfilled=run;return}function doRun(){Module[\"calledRun\"]=true;if(ABORT)return;initRuntime();readyPromiseResolve?.(Module);Module[\"onRuntimeInitialized\"]?.();postRun()}if(Module[\"setStatus\"]){Module[\"setStatus\"](\"Running...\");setTimeout(()=>{setTimeout(()=>Module[\"setStatus\"](\"\"),1);doRun()},1)}else{doRun()}}function preInit(){if(Module[\"preInit\"]){if(typeof Module[\"preInit\"]==\"function\")Module[\"preInit\"]=[Module[\"preInit\"]];while(Module[\"preInit\"].length>0){Module[\"preInit\"].shift()()}}}preInit();run();if(runtimeInitialized){moduleRtn=Module}else{moduleRtn=new Promise((resolve,reject)=>{readyPromiseResolve=resolve;readyPromiseReject=reject})}\n\n\n return moduleRtn;\n}\n);\n})();\nif (typeof exports === 'object' && typeof module === 'object') {\n module.exports = createMd4cModule;\n // This default export looks redundant, but it allows TS to import this\n // commonjs style module.\n module.exports.default = createMd4cModule;\n} else if (typeof define === 'function' && define['amd'])\n define([], () => createMd4cModule);\n"],"mappings":"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","ignoreList":[]} +\ No newline at end of file diff --git a/node_modules/react-native-enriched-markdown/lib/typescript/src/EnrichedMarkdownNativeComponent.d.ts b/node_modules/react-native-enriched-markdown/lib/typescript/src/EnrichedMarkdownNativeComponent.d.ts index 1ee4eda..b415d18 100644 --- a/node_modules/react-native-enriched-markdown/lib/typescript/src/EnrichedMarkdownNativeComponent.d.ts @@ -2228,14 +2420,32 @@ index 781adb1..4d4fa0c 100644 /** When false, task list checkboxes render read-only and ignore clicks. */ enableTaskListItemToggle: boolean; diff --git a/node_modules/react-native-enriched-markdown/src/web/wasm/md4c.js b/node_modules/react-native-enriched-markdown/src/web/wasm/md4c.js -index 26a61d7..4f82a68 100644 +index 26a61d7c3..88e2da25e 100644 --- a/node_modules/react-native-enriched-markdown/src/web/wasm/md4c.js +++ b/node_modules/react-native-enriched-markdown/src/web/wasm/md4c.js -@@ -1,2 +1,2 @@ +@@ -1,2 +1,20 @@ -var createMd4cModule=(()=>{var _scriptName=globalThis.document?.currentScript?.src;return async function(moduleArg={}){var Module=moduleArg;var ENVIRONMENT_IS_WEB=true;var ENVIRONMENT_IS_WORKER=false;var programArgs=[];var thisProgram="./this.program";var scriptDirectory="";var readAsync;if(ENVIRONMENT_IS_WEB||ENVIRONMENT_IS_WORKER){try{scriptDirectory=new URL(".",_scriptName).href}catch{}{readAsync=async url=>{var response=await fetch(url,{credentials:"same-origin"});if(response.ok){return response.arrayBuffer()}throw new Error(response.status+" : "+response.url)}}}else{}var out=console.log.bind(console);var err=console.error.bind(console);var wasmBinary;var ABORT=false;class EmscriptenEH{}class EmscriptenSjLj extends EmscriptenEH{}function binaryDecode(bin){for(var i=0,l=bin.length,o=new Uint8Array(l),c;i>8&c}return o}var runtimeInitialized=false;function getMemoryBuffer(){return wasmMemory.buffer}function updateMemoryViews(){if(HEAP8?.buffer?.resizable)return;var b=getMemoryBuffer();HEAP8=new Int8Array(b);HEAP16=new Int16Array(b);HEAPU8=new Uint8Array(b);HEAPU16=new Uint16Array(b);HEAP32=new Int32Array(b);HEAPU32=new Uint32Array(b);HEAPF32=new Float32Array(b);HEAPF64=new Float64Array(b);HEAP64=new BigInt64Array(b);HEAPU64=new BigUint64Array(b)}function preRun(){var preRun=Module["preRun"];if(preRun){if(typeof preRun=="function")preRun=[preRun];onPreRuns.push(...preRun)}callRuntimeCallbacks(onPreRuns)}function initRuntime(){runtimeInitialized=true;wasmExports["__wasm_call_ctors"]()}function postRun(){var postRun=Module["postRun"];if(postRun){if(typeof postRun=="function")postRun=[postRun];onPostRuns.push(...postRun)}callRuntimeCallbacks(onPostRuns)}function abort(what){Module["onAbort"]?.(what);what=`Aborted(${what})`;err(what);ABORT=true;what+=". Build with -sASSERTIONS for more info.";var e=new WebAssembly.RuntimeError(what);throw e}var wasmBinaryFile;function findWasmBinary(){return binaryDecode('asm¬`````````````` ````||`~`|``Tenv __cxa_throwenv\r__assert_failenv _abort_js\nenvemscripten_resize_heap˜–\n\r\n\n\n   \r     \r \n  \n  p44€€@ A à€ ¢memory__wasm_call_ctors\rparseMarkdown__indirect_function_table_emscripten_stack_restore—_emscripten_stack_alloc˜emscripten_stack_get_current™ JA 3” \rq !"#$%&\'()s*B=DZfghq*‚‚„’†*‘އ*‹‰*“•–• (\nªº–æAàÚB7AèÚA6A÷ÚA:AìÚAØ\r(6AðÚAÜ\r-:AñÚA:AƒÛA:AøÚA±\r/;AúÚA³\r-:AûÚA:AÛA:A„ÛAŠ(6AˆÛAŽ-:A‰ÛA:A›ÛA :AÛA™ )7A˜ÛA¡ -:A™ÛA:A ÛB칻֮سå7A«ÛA:A¨ÛA:A·ÛA:A¬ÛAá\r(6A°ÛAå\r/;A²ÛA:A¸ÛAt"6A¼ÛB‹€€€€‚€€€7 AÆ(6 A¿)7 A: AÏÛA:AÄÛA¦ (6AÈÛAª -:AÉÛA:AÛÛA:AÐÛAÈ (6AÔÛAÌ -:AÕÛA:AÜÛAt"6AàÛBŽ€€€€‚€€€7 AÖ)7 AÐ)7 A: AëÚ,AH@AèÚ(AàÚ(k õ”!~#A0k"$@ E@@A€\\"AèÚ("AÿÿÿÿqAkA\nAëÚ,"AH""M@AàÚ(AàÚ !@  @ A€ ü\n AëÚ- Av ÀAH@AäÚ 6  AëÚ Aÿq:  jA:  AàÚ   kAäÚ( "A  A€x AàÚAàÚ(AëÚ,AN  A:,  AG:/  AG:.  AG:-  AG:+  AG:*  AG:)  AG:(  AG:\'A$t"A6 B7 B7 B7 B7 A j" 6 ! \\"A÷ÿÿÿO\r@@ A O@ Ar"Ajt!  Aÿÿÿÿk6  6  6   : A j! E\r E\r  ü\n  jA: Aj! A\'j!#AÐk"$@ A j"( , " AH"E@A<t"B7 Aì6 B7 B7 B7 B7$ B74 B€€€ü7,  6  A j6  (! AéOA4 Aèn" A4OA jA !A<t" B7 Aì6 B7 B7 B7 B7$ B74 B€€€ü7,  A j6 (!  6@ E\r (" Ak6 \r (( r Aj! ("\n! ( " \nG@@@ Ak(" E\r ("Ak6 \r (( r \n Ak" G\r (!  \n6 @A€  A€O" ( kAuM\r At"t! \n k"\n@ \nü\n   j6  \n j6  6 E\r k !@@@@ (" ("\nI@ (6 ("6 @  (Aj6 Aj!  ("k" Au"Aj" A€€€€O\rAÿÿÿÿ \n k"\nAu"  K \nAøÿÿÿO" A€€€€O\r At"\nt" j" (6 ("6  \nj!\n   (Aj6 ( ( ("k" Au  Atk! @   ü\n  \n6  Aj" 6  6 E\r k  6    Aj! @ ,AH@ (A: A6  A: A: A€z (" (  , AH6 -! -! -! -! -! -! -!\r -! -! B7( A6$ A6 A6 A6 A6 A6  A tAìžAà– r \rAtr Atr Atr Atr Atr Atr Atr6 (  , "AH"! ( ! !\n#A€k" $@ A j"(@A! ("E\rA›    A4jAAüü 6 6 )7 )7 )7 )7$ ( 6, \n60 AA ("Aq6œ A„j"AA€ü A;ã A:® A;à A:ß A: A;¿ A:ª A:¥ A:„ A€„q@ A:‚ A€€q@ A:â A€ q@ A:¨ A€€€q@ A:Á A€€€q@ A:¯ Aq@ A:Ä Aq@ A:¾ A€q@ A:² A€Âq@ A:€ Aq@A!@ A G A GqE@ jA: Ar"AýqA F@  jA: Aj"A€G\r A E\rA  jAk-"A\rF\r A\nF ! A6` A 6D 64 A€€  A€€OAt6X A„jAÿAÔü B7ä B7Ü@AA \n ("E@ AÌj!" A°jAr!# Aüj!$ AèjAr!% A°j!\rAè! A!@@ \r!@@@@ (" K@ B7ø B7ð B7èA! A°jAA \r A°jF"j \r \rF"!\r (¨!& (!@@ j-"A G A Gq\r A|qAj Aj A F! Aj" G\r ! A°jA,A j Aj " 6 A°jA$A j A j " 6A! A°jA A j Aj " A6@ (”"AL\r (œ! (! !\n@@  Alj"-A>F@ \n O\r O\r j-A>G\r Aj"!@ Aj" O\r@ j-"\nA G \nA Gq\r A|qAj Aj \nA F! Aj" G\r !   kAkA  G"\n6  6 !  \n ( "I\r  \n k"\n6 ! Aj" G\r ! ! 6ä@@ O\r j-A\nk  L\r (!@  Alj-A>F\r Aj" G\r ! " #  Aj !A!\nA!A! !@A k!A k! („"\' (üjAk!( (¬E! (!! ( !) (œ! (¤!@@ ("AG@ !   6@  ("M@ !  !@ O\r  ( j-!@  j- AÿqG\r Aj" G\r ! @  k )I\r@  O\r@@  j-A k Aj" G\r ! 6ä \rA6  6ä  F@   (k"A M6 \rA6  (! @@@@ AG\r AL\r  L\rA! A6¤  O\r  j"-A\nk @ Aj  Aäj+AL\r A6¤ AþÿÿÿqAG\r \rA6 A6 ! \rA6  @ AG\r  (”G\r \rA6  (" (œk"A O6  \rA6@@ AL"\r G\r ( AljAk-"A>G6¨  A6¨ @ ! ( AljAk-! AÿqA>F@ !  G@ !  (€\r („"A H\r (ü jAk-AG\r A6¬  @ Aq@ !    AL\r  (” G\r  ! Alj"Ak-A>F\r  G\r  (€\r  \'A H\r  (-AG\r  6A AF\r   A$k(k"A M6 Ak ! A6¬ A6¨@ (" O\r@ AG\r@ -"A-k  G\r@@ Aj" O\r@  j-F@  Aj"K\r  @@ j-A k Aj" G\r ! 6ä \rA6 AA A=F6   \nI\r -"E\rA­ ÀAPE\rA! Aj"\n O\r@@@  \nj-" AÿqF"\r A F\r A G\r j! \nAj"\n G\r !\n AI\r  AI\r A\nk @@@  L\r G\r@ Aj   Aàj Aèj,E\r -è"A>F\r ! Alj"-G\r (ð" ( K\r (ô" k j" !@ (à" O\r@ j-"A G A Gq\r A|qAj Aj A F! Aj" G\r 6ä   k6  6 !  6ä   k" 6  6 O\r@ j-A\nk M@ j"6ô A6  Aj"6ô  Ak6  ! @  O@ (AF@ !  \rA6   k6 A6 ! \n Aj   Aäj Aèj,! (!@@@@@ @ (ä!@ AG\r  G\r@@ O\r j-"A\rF\r -è! A\nG\r AÿqA>F\r  A>! -èA>G\r Aÿq"A.G A)Gq\r (ìAG\r (ô" (ðk j"!@ O\r@ j-"A G A Gq\r A|qAj Aj A F! Aj" G\r ! 6ä   k"6  6  ,è6@@@ O\r j-A\nk Aj6ô   M@  j6ô A6  Aj6ô  Ak6 E@ Aj j-\r (”! @ (˜" J@ (!  A Av j AL"6˜ ( All"E@ (("E\rAõ (0   6 (”! Aè  F! Aj! Aj6”  Alj" )ø7  )ð7  )è7 (”! (! (! ! \n A F  Fq\r (ä! ! O@ !  @ j"\n-"A#G@ ! AþF\r AàF\r !  Ak"\nF\rA!  Aj"j-A#F\r  @@  j- G\r Aj" G\r !  k"AI@ !  6 @@@  O\r@  j-A G\r Aj" G\r   O\r@@  j-"A\nk @ AàG\r \n-AàG\r !  Aj" G\r ! 6ä \rA6 A6 A6 \r \rA 6  \nF\rA!  Aj"j-A#G\r  \nF\rA!  Aj"j-A#G\r  \nF\rA!  Aj"j-A#G\r  \nF\rA!  Aj"j-A#G\r  \nF\rA!  Aj"j-A#G\r  \nF\rA! Aj!   k! ! AJ@ !  @  O"\n\r (Aq\r  j-A k"AK@ !  A tA“€€q\r !  @ \n\r@  j-"A G A Gq\r Aj" G\r !  6 6ä \rA6  6 @@@@@  O\r  j-AF\r Aj"\n O\r A/G\r \n j-A>F\r  AjM@A!  A! AA   A j>E\rA! ( "\n O\r (!@@  \nj-"A k"AK\rA tA€€qE\r \nAj"\n G\r  AAA A\nF A\rF! Aj$ 6¤@  (AG\r A6¤ ("A€qE\r (AG\r  (O\r ( j-"A-k Aj  Aäj+ F@ A6¤ A6 \rA6 AüG\r  (”G\r (€"E\r (AG\r Aäj! Aàj!A!A!@ Aj"(" M\r (" j-AüG\rA! Aj" O\r@  j-A k"\nAK\rA \ntA€€qE\r Aj" G\r ! @@@@  I@  ( j-A:Fj!  O\r ("\n j-A-G\r@@@  \nj-"A-G\r Aj" G\r Aj!  A! Aj!@  A:Fj" O\r@@  \nj-"A k"AK\rA tA€€qE\r  Aj"G\r  AüG\rA!A! Aj" O\r@  \nj-A k"AK\rA tA€€qE\r Aj" I\r !   O\r@  \nj-A\nk E\r  ! E\r  6  6A  A E\r  (à6 \rA\n6 \rA6 (”"  F  (AF! A€qE\r jAL\r ( Alj"Ak-"E\r A?K\rB ­†B€€€€ÀƒP\r@ (ä" ("\n Aj"  \nK"O\r (!@ j-"A G A Gq\r Aj" G\r ! Aj" \nO\r (" j-AÛG\r  Aj"j,"E\rAÓ APE\r  j-AÝG\r \n Aj"G@ j-A k"AK\r A tA“€€qE\r Ak % " -Ar: Ak $  6@ ("O\r (!@ j-A k"AK\rA tA€€qE\r Aj" G\r ! 6ä  6  Aj"6ô  6  6Aè!A! ! ! Aj.A! Aj A@k/\r -Aq@ Aj AÜj/\r AjA-\r Aj0\rA!#Ak" $ A6$ Aj"\rA6@ \r(€AJ@ Aøj!@@@@@@ \r(ø j" ("AÿqAk AsA\nvAq6 /:  (6 (AsA\nvAq6 /:  AÿÿK6 /: (6  A6 /At(€\\"6 /! 6 At(€6 Aj6 A$j6 @@ ("A€q@@ A€qE\r Aÿq A j \r(, \r("@ \r($"E\rA¿ \r(,   ("Aÿq"AK\rA tAŽ€qE\r \r \r(Ak6 (! A€qE\r Aÿq A j \r(, \r("@ \r($"E\rAš \r(,   @ ("AÿqAk \r(Œ \r(Alj" -Ar: \r \r(Aj6  B7` B7X B7P B7H B7@ B78 B70 B7(@ ("AÿqA\nG\r A€€„I\r ("A€ Av"nM\r Aq! Aj!A!\nA!@ "AO@ A|q!A!@  Atj"( j ( j (j (j ( ( ( (jjjk! Aj! Aj" G\r E\r @  Atj"( j (k! Aj! \nAj"\n G\r  n AvO\r \r($"A¸ \r(,  (  A€~qA r"6 A! A6ˆ B7€ B7x B7p B7h \r("@ \r(Œ AljAk-As! A!@@@@@@@ AÿqAk Av6h  A€€I\r \r("\n ("j-! ( !@@@  \r("O\r@  \nj- AÿqG\r Aj" G\r  M\r@  \nj-A G\r Aj" G\r ! @  M\r@  \njAk-A G\r Ak" K\r ! A! \r  \nj  kA Aèj AÈj9\r \r(! !\n@  M\r@  \nj-A k"AMAA tA€€q\r \nAj"\n G\r !\n \r  j \n kA  A(j9\r :ˆ (!A!  A6l Av6h (Ak6p  Av6h @@@@@@@  Aÿq"A FqE@  Aèj \r(, \r("\r (! AÿqAk \r($"E\rAš \r(,   (!@ AÿÿM@ E\r Aj!@ ( (F@ A j! Ak"\r  @  A lj"A k( Ak(G\r Ak"\r  Ak"E\r Aj! \rA  :"E\r  \rA Aj (:"E\r  (!@@ Av"Atj"E@A! \r($"E\rAä \r(,  k  @ (! ("! ! !@ !@ M\r \r(!@  j-A-F\r Aj" G\r ! A!  K@ \r( jAk-A:F! @ M\r \r(!@@  j-"\nA-G\r Aj" G\r !  Ar  \nA:F!  At( 96 Ak! Aj! AJ\r A A \r(, \r("@ \r($"E\rAš \r(,  k  \rA ( (  ;"\rA A \r(, \r("@ \r($"E\rA¿ \r(,  k  AI\r@A A \r(, \r("E@ Aj!A!  \r($"E\rAš \r(,  k  @ \rA  Atj"( (  ;"\r Aj" G\r A A \r(, \r("E\r \r($"E\rA¿ \r(,  k  k  \r Aj (<"\r A!  -"A Fq\r  Aèj \r(, \r("E\r \r($"@A¿ \r(,  ! \r (X@ (Hk (Lk (Pk (8E\r ((k (,k (0k \r (! -AkAM@ A l j!  At j!  \r(Œ \r(Alj" -Aþq A\nvAqr: \r \r(Aj6 Aj" \r(€H\r \rA6€A! Aj$ "\r -Aq@A!A!#A@j"\n$@ Aj"(`"E\r (pE\r (X AAR@@AA (, ("E@ (`E\r \nA0j!  ($"E\rAš (,   @ (X Alj"( E\r \nB7 \nB7 \nB7 \nB7 B7 B7 \n ( 6( \n (6,@ ( (A  \nAj9@A!  A \nA(j (, ("@ ($"E\rAš (,   ( (<"\rA \nA(j (, ("E@A!  ($"E\rA¿ (,  \n(@ \n(k \n( k \n(k \r Aj" (`I\r A!AA (, ("E\r ($"@A¿ (,  ! \nA@k$ "\r A!AA (0 ("E\r (("@A¿ (0  !  \n6ä \rA6 !  ! !  A6¨ ! @ (ä"Aj" ("O\r (!@@ j"-A\nk @ -A\nk @ -A\nk @  j-A\nk Aj! Aj!  I\r @ I@ (!@A!@ j-A\nk Aj" G\r ! A! A°jA(A j Aj "\n 6 " \r("AG\r@@ ("M\r (!@  jAk-"A G A Gq\r Ak" K\r  @  O\r (!@  jAk-A#G\r Ak" K\r   F\r ( jAk-"A F@ !  A F@ !  ! -AqE\r \n 6  !@ AkAI\r  ("M\r (!@  jAk-"A G A Gq\r \n Ak"6  K\r @ ( j-A\rFj! I@ ( j-A\nFj! @ &E\r E\r  j"AL\r ( Alj"Ak-A>F\r (ü Ak(j" (A€r6 @ \r  j" (”N\r Aj -\r AJ@ AjA Al" (j"(" -Aq ( j,A A1\r AjA (ü" -éAq" ( j,A A1\r ( j" -Aýq r: ( j 6 @ (”!@ -AqE\r ( Alj"Ak-A>G\r \r(AG\r \n(" ("k"AkA K\r (" j"-AÛG\r -A!G\r  jAk-AÝG\r Ak! Aj!A!@@@@ Ak @  j-"A k  AákAÿqAIAÿq -¹"A k  AákAÿqAIAÿqG\r Aj" G\r A  @  j-"A k  AákAÿqAIAÿq -Î "A k  AákAÿqAIAÿqG@ A\nk Aj" G\r A  A!@  j-"A k  AákAÿqAIAÿq -ú "A k  AákAÿqAIAÿqG@ A\nG\r  Aj" G\r A  A!@  j-"A k  AákAÿqAIAÿq -‡"A k  AákAÿqAIAÿqG@ A\nG\r -"A k  AákAÿqAIAÿqAÃG\r -"A k  AákAÿqAIAÿqAÁG\r -"A k  AákAÿqAIAÿqAÕG\r -"A k  AákAÿqAIAÿqAÔG\r -"A k  AákAÿqAIAÿqAÉG\r -"A k  AákAÿqAIAÿqAÏG\r -"A k  AákAÿqAIAÿqAÎG\rA  Aj" G\r A ! Ak" -Ar: ( (”AljAk" -AÇq r: \rA6 (”!  k!@A!@@A ( Alj"-A)kt"AqE@ A!qE\rA! Aj.  („6 Aj  ( ,A1\r AjA (" -Aq ( j,A A1\r  AjAA -"AqA AvAqA1\r Aj" (”H\r @ \r(E@ Aj.@A!  A!Aè! -AÀqE\r ( \n(I\r (ŒAj6Œ  (Œ@@ („"Aj" (ˆ"J@ A€ Av j AL"6ˆ (ü l"E@A! (("E\rAõ (0   (€"@   (ükj6€ 6ü („"Aj6„  6„ (ü"\rA!   j"A; (Œ! A6  AtAr6 A6Œ @ (E\r Aj.E\rA!  @@@@ \r("Ak\n A! Aj.\r („"Aj" (ˆ"J@ A€ Av j AL"6ˆ (ü l"E@ (("E\r\nAõ (0  \n (€"@   (ükj6€ („"Aj6„ 6ü  j  6„ (ü"E\r  j " \r(AÃÌj-"; (! A6   Atr6 6€ Aj \r2\r Aj.\rA!Aè!  (€A: (€ /; (€" (A€r6A! Aj \r2\r Aj.\rA! (€E@Aè!  \rA6 \r!  (€A\n: (€ /; A 6AA Aj \r2!  @  (F\r Aj.E\rA!  @ (€\r \r! @ Aj"(€"Aj"\n („"J@ A€ Av j AL"6„ (ø l"E@A ($"E\rAõ (, A  (ü"\n@   \n (økj6ü  6ø  (€"\nAj6€  \nj   \n6€ (ø"E\r  j " \r(AÃÌj-"\n; \r(! A6  \n Atr6  6üA  A E\rA!  Aj \r2! A! E\r  A!  (("E\rAš \n  (P"@ (T"A!@@ (P Atj("E\r (@" M@   (D (HljI\r k (T! Aj" I\r (P k (H@A!@ (@ Atj"-"Aq (k -  Aq@ ( k Aj" (HI\r (@k (l"@ (p"A!@@ (l Atj("E\r (\\" M@   (` (dljI\r k (p! Aj" I\r (l k (d@A!@ (\\ Alj(k Aj" (dI\r (\\k (8k (xk (ük (k A€j$ @A<t"B7 Aì6 B7 B7 B7 B7$ B74 B€€€ü7,  6  A j6  (@ (("E\r ((" ($"G A$j!A!\r@@@  \rAt"\nj("(AF@ ($" (("G\r \rAj!\r   k"Au!@@ ((AF\rA! AG@@ Aj!  Atj"((AF@  O\r Ak(!  Atj(! \r \r  "G\r A! A68 B70A!  A! A68 B70 A6L B7D  A0j6@  AÄj6<@@@@@@  At"j"(" (AG\r  Ak(A !  Aj"K@  Atj( rAG\r AF\r @ Aj" O\r -"A k  AákAÿqAIAÿqAÓG\r -"A k  AákAÿqAIAÿqAÃG\r -"A k  AákAÿqAIAÿqAÒG\r -"A k  AákAÿqAIAÿqAÉG\r -"A k  AákAÿqAIAÿqAÐG\r -"A k  AákAÿqAIAÿqAÔG\r  j-A>F\r @ Aj" O\r -"A k  AákAÿqAIAÿqAÓG\r -"A k  AákAÿqAIAÿqAÔG\r -"A k  AákAÿqAIAÿqAÙG\r -"A k  AákAÿqAIAÿqAÌG\r -"A k  AákAÿqAIAÿqAÅG\r  j-A>F\r A\nj" O\r -"A k AákAÿqAIAÿqAÔG\r -"A k AákAÿqAIAÿqAÅG\r -"A k AákAÿqAIAÿqAØG\r -"A k AákAÿqAIAÿqAÔG\r -"A k AákAÿqAIAÿqAÁG\r -"A k AákAÿqAIAÿqAÒG\r -"A k AákAÿqAIAÿqAÅG\r - "A k AákAÿqAIAÿqAÁG\r  j-A>F\r\r Aj" G\r !  6A Aj" O\r Ak! (!@@  j"-A\nk\n\n /A­Ús -A>srE\r Aj! Aj!  I\r !  Aj" O\r Ak! (!@@  j"-A\nk /A¿üF\r Aj! Aj!  I\r !  Aj" O\r Ak! (!@@@  j-"A\nk  A>F\r Aj! Aj!  I\r !  Aj" O\r Ak! (!@@  j"-A\nk /Aݺs -A>srE\r Aj! Aj!  I\r !  @@  O\rA! ( j-A\nk  6 ( !   6A  6A  6A  6A  6A  Aj6A Å@  ("O\r  (˜O\r @ (" j-"E\r A>F@ A>:  6  -Aüq: Aj! Aj  A?K\rB ­†B€€€€€ ƒP\r  Aj"K@  j-A k"AK\rA tA“€€qE\r  :  6  -Aüq: Aj  A! A6  A j"  I"\nO\rA! !@@ j-" A0kAÿqA K\r  A\nljA0k"6 Aj" \nG\r \n! M\r O\r@ j-" A)k  Aj"K@  j-A k"AK\rA tA“€€qE\r  :  6  -Aüq:  k jAj 6  6A!  ç  ("H@@A!@@@A (Œ Alj"Ak"-A)kt"AqE@ A!qE\rA! Ak(!A! Ak-Aq@ ( j,! A! A  A1\r A ,A1\r  AA Ak-"AqA AvAqA1E\rA!  (Ak"6  H\r A Ú#A0k"$@ (ü"E\r@@@ ("AÿqAk A€qE\r (" (O\r ( j-AÛG\r@ ("E\r Aj! AG\r !  @ \r@ A/G\r Aj" O\r \n j-A>F\r AL\r@ AßqAÁkAÿqAI\r AßF\r A:G\r  Aj"M@A!  @@@ \nj,"A0kAÿqA\nI\r A_qAÁkAÿqAI\r E@A!  A  APE\r A!  Aj"G\r  A!  A! @@ Ak A=G\r Aj!A!  A+!@@@@ A"k E\r Aá AP\r A\rF\r A)!  A*! Aj! I\r A! E\r \rF\rA  A)FA !  Aj" Atj"(! (" I\r   M@A A!  Aj6 „#Ak"$@  O\r@@@ j"  k A j4"AÿK@A!A!@@@  jAm"AtA j("\nAu j"AtA j(Aÿÿÿq K@ Ak!   \nAvAq j"AtA j(AÿÿÿqM\r Aj!  L\r  AH\r  A F\r A F\r A kAI\r -A\nk ( j" I\r Aj$  à@@@ AÿK@A­!@@@  jAm"AtAÀj("Au j"AtAÀj("Aÿÿÿq K@ Ak!  AvAq j"AtAÀj(AÿÿÿqM\r Aj!  N\r  AH\rAÐ8!  A6  A r AÁkAI6 A!A4!@@@  jAm"AtAÀ1j("Au j"AtAÀ1j("Aÿÿÿq M@ AvAq j"AtAÀ1j(Aÿÿÿq O@ AH\rAà8!  Aj!  Ak!  N\r A!A!@@@  jAm"AtAÐ6j("Au j"AtAÐ6j("Aÿÿÿq M@ AvAq j"AtAÐ6j(Aÿÿÿq O@ AH\rAð8!  Aj!  Ak!  N\r A6  6  ( ( " lAtj! At"@   ü\n  6 F\r ( Aÿÿÿq"AjF@  sAsAq j6  ( kj6 õ #A k"$ B7 B7 B7 B7 A ?! A ?! @@@  K@   M\r @ \nE@   AjC!A! AqE@   C! A!  Atj( Aj Atj(k"\r Aj" ( " I! Aj" (" I!\n  K\r  I\r  K\r  I\r A! A j$  iA!@ ("(" ("("I\rA!  K\r ( ( ( (A"\rA! (" ("I\r K!  ‰#Ak"$@@@  O\r j  k A j4! ( j! AÿK@A!@@@  jAm"AtA j("\nAu j" AtA j(Aÿÿÿq K@ Ak!   \nAvAq j"AtA j(AÿÿÿqM\r Aj!  L\r  AN\r  A F\r A F\r A kAO\r A6 A 6  ?!   @ Aj$  D ("(" ("("I@A  K@A ( ( ( (A ›”#A0k"$ A6x#Ak"$ AjAA€ü @@ E\r Ak! A€j!  AtjAk!@  Atj"(!@ !@ !@ Aj" ("O@ !  (! @  j"-j-@ !  -j-@ !  -j-@ !   j-j-@ !  Aj! Aj"!  K\r @  K@ (!@  j"-" j-\r Aj" G\r Aj" I\r  @AA@@@@@@ AÜF@A! Aj" (O\r@  j-"A!kAÿqAI\r@ AÿqA\nku Aj I\r Aj! @@ (x" (|"N@ AÀ Av j AL"6| (t All"\rA! ($" E\rAõ (,   Aj6x (t"\rA!  6t (x"Aj6x  Alj"AÜ ; B7  Aj"6  6 A!@@@@@@@@@@@@ A!k\\ \r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\n\r \r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r Aj"\r!\n@  \rM\r@  \nj- G\r \nAj"\n I\r !\n A!A!A!  (F\r N"AÿM\rA!A!@@@@  jAm" AtA j("Au j"AtA j(Aÿÿÿq K@ Ak!   AvAq j"AtA j(AÿÿÿqM\r Aj!  N\r  A! AN\r A!Aä!@@@  jAm" AtA°9j("Au j"AtA°9j(Aÿÿÿq K@ Ak!   AvAq j"AtA°9j(AÿÿÿqM\r Aj!  N\r A! AN   k! !@@  j-" AàG\r Aj" G\r !A  A F ! !  k"A K\r At j( "\r  AtjAk(O\rA!A!@ E@ ! !\n  !\n \r " I\r @@@@ \nO\r@  j-"\rA G@ \rAàF\rA! Aj" \nG\r A! \n  !\r \nO@A! !  @  \rj-AàG"@ ! \r!  \rAj"\r \nG\r ! \n! @  k"\rF@A!\n  Atj"("\r I@  jAk-A F!\n As  Gq\r \r \rF \nrE\r E\r Aj  @ F\rA! \rAK\r \rAt jA j"\r \r("\r \rK6 \r  Aj"M@A!   Atj"\n(! \n(!\n  ( ! \n@ Ak!  Ak(" ("O\r@  j-"A G A Gq\r Aj" G\r ! @@ (x" (|"N@ AÀ Av j AL"6| (t All"\rA! ($" E\rAõ (,   Aj6x (t"\rA!  6t (x"Aj6x  Alj"Aà; B7  6  6@@ (x" (|"N@ AÀ Av j AL"6| (t All"\rA! ($" E\rAõ (,   Aj6x (t"\rA!  6t (x"Aj6x  Alj"Aà; B7  6  6 (t (x"Alj"Ak" Ak6 A(k" Ak6  -Ar:  -Ar:A! ! ! ! (M\r@@@   jAv"Atj"( K@ E\r  AtjAk( I\r Ak!  (K\r ! !  Aj! @@ (x" (|"N@ AÀ Av j AL"6| (t All"\rA! ($" E\rAõ (,   Aj6x (t"\rA!  6t (x"Aj6x  Alj"A¦; B7  Aj"6  6  (x"AL\r (t" AljAk-A&G\r (|" L@ AÀ Av j AL"6|  All"E@A! ($" E\rAõ (,   6t (x! Aj6x  Alj"A»; B7  Aj6  6  ("\n - AÀq\r\n   k"  \n A j>\r (" AjM\r -A!G\r  Aj"j-A-G\r -A-G\r A! (è" K  \nAkOq\r @ Aj" \n \nI"\rM@  j" /A­Ús -A>srE\r\r@@ Aj! Aj" \rK\r " j" /A­Ús -A>sr\r  !  \nI  Aj" Kq@  Atj"(! (!  6è (! A! -AqE\r Aj" O\r  j-AüG\r@@ (x" (|"N@ AÀ Av j AL"6| (t All"\rA! ($" E\rAõ (,   Aj6x (t"\rA!  6t (x"Aj6x  Alj"Aü; B7  Aj"6  6  ("Aj K\r  Ak"\rj"/A÷îs -A÷sr\r @  \rF\r \rN"AÿK@A!A!@@@@  jAm" AtA j("\nAu j"AtA j(Aÿÿÿq K@ Ak!   \nAvAq j"AtA j(AÿÿÿqM\r Aj!  N\r  AN\r A!Aä!@@@  jAm" AtA°9j("\nAu j"AtA°9j(Aÿÿÿq K@ Ak!   \nAvAq j"AtA°9j(AÿÿÿqM\r Aj!  N\r  AH\r\r  A F\r A F\r A\rkA}K\r A!kAI\r A:kAI\r AÛkAI\r AÿG AúKqE\r @@ (x" (|"N@ AÀ Av j AL"6| (t All"\rA! ($" E\rAõ (,   Aj6x (t"\rA!  6t (x"Aj6x  Alj"A®; B7  Aj"6  \r6@@ (x" (|"N@ AÀ Av j AL"6| (t All"\rA! ($" E\rAõ (,   Aj6x (t"\rA!  6t (x"Aj6x  Alj" (6 (! AÄ; B7  6  Aj!@@ (" Aj K\r  Ak"\nj(AèèуG\r  M\r /A¯ÞF\r @ Aj K\r  Ak"\nj"\r(Aèèуs \r-Aósr\r  M\r /A¯ÞF\r Aj K\r  Ak"\nj"/Aæès -Aðsr\r  M\r /A¯ÞG\r @@ (x" (|"N@ AÀ Av j AL"6| (t All"\rA! ($" E\rAõ (,   Aj6x (t"\rA!  6t (x"Aj6x  Alj"Aº; B7  6  \n6@@ (x" (|"N@ AÀ Av j AL"6| (t All"\rA! ($" E\rAõ (,   Aj6x (t"\rA!  6t (x"Aj6x  Alj" (6 (! AÄ; B7  6 Aj!  (Aj K\r @ Ak-"AßqAÁkAÿqAO@ Aj O\r A0kAÿqA\nO\r  Aj O\r\n  Aj"j-"A0kAÿqA\nO@ A_qAÁkAÿqAK\r\n @@ (x" (|"N@ AÀ Av j AL"6| (t All"\rA! ($" E\rAõ (,   Aj6x (t"\rA!  6t (x"Aj6x  Alj"AÀ; B7  6  6@@ (x" (|"N@ AÀ Av j AL"6| (t All"\rA! ($" E\rAõ (,   Aj6x (t"\rA!  6t (x"Aj6x  Alj" (6 (! AÄ; B7  6 Aj!  @@ (x" (|"N@ AÀ Av j AL"6| (t All"\rA! ($" E\rAõ (,   Aj6x (t"\rA!  6t (x"Aj6x  Alj"AÝ; B7  Aj"6  6 \r @@ (x" (|"N@ AÀ Av j AL"6| (t All"\rA! ($" E\rAõ (,   Aj6x (t"\rA!  6t (x"Aj6x  Alj" 6A!A  Aj" O\r  j-AÛG\r@@ (x" (|"N@ AÀ Av j AL"6| (t All"\rA! ($" E\rAõ (,   Aj6x (t"\rA!  6t (x"Aj6x  Alj" 6A!!A !  :  : B7   j"6@@ (x" (|"N@ AÀ Av j AL"6| (t All"\rA! ($" E\rAõ (,   Aj6x (t"\rA!  6t (x"Aj6x  Alj"AÄ; B7  6  6@@ (x" (|"N@ AÀ Av j AL"6| (t All"\rA! ($" E\rAõ (,   Aj6x (t"\rA!  6t (x"Aj6x  Alj"AÄ; B7  6  6 \n @@ E@  -\rA qAvq\r  E\r @@ (x" (|"N@ AÀ Av j AL"6| (t All"\rA! ($" E\rAõ (,   Aj6x (t"\rA!  6t (x"Aj6x  Alj"A:  : B7  Aj"6  6 \n @@@@@@@@@@@AA@@AA@@@@@@@@@@@@@@ >\r"""""""" " """"""""""""""""""" """""""""""""""""""""""""" AÞF\r AþG\r!A! Aj"\n!@  \nM"\r@  j-AþG" \r Aj" I\r !  k"AG\r ( "A€€qE\r \rA! A!  \nj ( \nkA4"AÿK\r A F\r A F\r A kAM\rA  A! Aj" I\r -AqE\r Aj"!@  M\r@@  j-AÞG\r Aj" I\r ! !  kAG\r%A! A!  j ( kA4"AÿM@ A F\r A F\r A kAM\rA  @@@  jAm"AtA j("\rAu j"\nAtA j(Aÿÿÿq K@ \nAk!   \rAvAq j"AtA j(AÿÿÿqM\r Aj!  N\r A  \nAN\rA  A !  (F\r N"AÿM\rA!A!@@@  jAm" AtA j("\rAu j"\nAtA j(Aÿÿÿq K@ \nAk!   \rAvAq j"AtA j(AÿÿÿqM\r Aj!  N\r !  \nAN\r !  -A qE\r Aj" O\r@  j" -A=F@  Aj"K\r  !  kAG\r"A!A!AA ( kA4"AÿM@A! A F\r A F\r A kAI  @@@  jAm" AtA j("\rAu j"\nAtA j(Aÿÿÿq K@ \nAk!   \rAvAq j"AtA j(AÿÿÿqM\r Aj!  N\r A!\n \nAN !  -A€qE\r Aj" O\r@  j" -A+F@  Aj"K\r  !  kAG\r!A!A!AA ( kA4"AÿM@A! A F\r A F\r A kAI  @@@  jAm" AtA j("\rAu j"\nAtA j(Aÿÿÿq K@ \nAk!   \rAvAq j"AtA j(AÿÿÿqM\r Aj!  N\r A!\n \nAN !  @@@  jAm"AtA j("Au j"\rAtA j(Aÿÿÿq K@ \rAk!   AvAq j"AtA j(AÿÿÿqM\r Aj!  N\r A  \rAN\rA  A !  (F\r\r N"AÿM\r A!A!@@@  jAm" AtA j("Au j"\rAtA j(Aÿÿÿq K@ \rAk!   AvAq j"AtA j(AÿÿÿqM\r Aj!  N\r !  \rAN\r\r !  ! AK\r ( ! ! A€qE\rA!  (M\r N"AÿM\rA!\nA!@@@@  \njAm"\rAtA j(" Au \rj"AtA j(Aÿÿÿq K@ Ak!   AvAq \rj"\nAtA j(AÿÿÿqM\r \nAj!\n  \nN\r  AN\r\n A!\nAä!@@@  \njAm"\rAtA°9j(" Au \rj"AtA°9j(Aÿÿÿq K@ Ak!   AvAq \rj"\nAtA°9j(AÿÿÿqM\r \nAj!\n  \nN\r A! AN  @  j-A$F@  Aj"K\r  A! !  kAK\rA!  (M\r N"AÿM\rA!A! @@@@  jAm"\nAtA j("Au \nj"\rAtA j(Aÿÿÿq K@ \rAk!   AvAq \nj"AtA j(AÿÿÿqM\r Aj!  L\r  \rAN\r A!Aä! @@@  jAm"\nAtA°9j("Au \nj"\rAtA°9j(Aÿÿÿq K@ \rAk!   AvAq \nj"AtA°9j(AÿÿÿqM\r Aj!  L\r A!\r \rAN  @ Aj" O\r@  j-A k"AK\rA tA€€qE\r Aj" I\r ! A F@ !  kAI\r @@ (x" (|"N@ AÀ Av j AL"6| (t All"\rA! ($" E\r Aõ (,  Aj6x (t"\rA!  6t (x"Aj6x  Alj"A:  : B7  6  6  @@ (x" (|"N@ AÀ Av j AL"6| (t All"\rA! ($" E\rAõ (,   Aj6x (t"\rA!  6t (x"Aj6x  Alj"A€ ; B7  Aj"6  6  A F\r A F\r A\rkA}K\r AÿG AúKq A!kAI A:kAIr AÛkAIrr ! @ E\rA! A!@  j" ( k" A4"AÿM@ A F\r A F\r A kAO\r  @@@  jAm"AtA j("\rAu j"\nAtA j(Aÿÿÿq K@ \nAk!   \rAvAq j"AtA j(AÿÿÿqM\r Aj!  N\r  \nAN\r A!Aä!  A4"AÿM@ AÿG AúKq A!kAI A:kAIr AÛkAIrr  @@@  jAm" AtA°9j("\rAu j"\nAtA°9j(Aÿÿÿq K@ \nAk!   \rAvAq j"AtA°9j(AÿÿÿqM\r Aj!  N\r A!\n \nAN ! !  Aq "E\r @@ (x" (|"N@ AÀ Av j AL"6| (t All"\rA! ($" E\rAõ (,   Aj6x (t"\rA!  6t (x"Aj6x  Alj" : A$: B7  6  6  A F\r A F\r A\rkA}K\r AÿG AúKq A!kAI A:kAIr AÛkAIrr ! @ E\rA! A!@  j" ( k" A4"AÿM@ A F\r A F\r A kAO\r  @@@  jAm"AtA j("\rAu j"\nAtA j(Aÿÿÿq K@ \nAk!   \rAvAq j"AtA j(AÿÿÿqM\r Aj!  N\r  \nAN\r A!Aä!  A4"AÿM@ AÿG AúKq A!kAI A:kAIr AÛkAIrr  @@@  jAm" AtA°9j("\rAu j"\nAtA°9j(Aÿÿÿq K@ \nAk!   \rAvAq j"AtA°9j(AÿÿÿqM\r Aj!  N\r A!\n \nAN ! !  Aq "E\r @@ (x" (|"N@ AÀ Av j AL"6| (t All"\rA! ($" E\rAõ (,   Aj6x (t"\rA!  6t (x"Aj6x  Alj" : Aþ: B7  6  6  A F\r A F\r A kAM\r !  A! ! AqE\r @@ (x" (|" N@ AÀ Av j AL"6| (t All" \rA! ($" E\rAõ (,   Aj6x (t" \rA!  6t (x"Aj6x Alj" : Aþ: B7  \n6  6  A! !  kAG\r @@  (F\r N"AÿK@A!A!@@@  jAm" AtA j("\rAu j"\nAtA j(Aÿÿÿq K@ \nAk!   \rAvAq j"AtA j(AÿÿÿqM\r Aj!  N\r !  \nAN\r !  A F\r A F\r A kAM\r !  A! ! AqE\r @@ (x" (|" N@ AÀ Av j AL"6| (t All" \rA! ($" E\rAõ (,   Aj6x (t" \rA!  6t (x"Aj6x Alj" : A+: B7  6  6  A! !  kAG\r @@  (F\r N"AÿK@A!A!@@@  jAm" AtA j("\rAu j"\nAtA j(Aÿÿÿq K@ \nAk!   \rAvAq j"AtA j(AÿÿÿqM\r Aj!  N\r !  \nAN\r !  A F\r A F\r A kAM\r !  A! ! AqE\r @@ (x" (|" N@ AÀ Av j AL"6| (t All" \rA! ($" E\rAõ (,   Aj6x (t" \rA!  6t (x"Aj6x Alj" : A=: B7  6  6 A F\r A F\r A kAM\r !  A! ! AqE\r @@ (x" (|" N@ AÀ Av j AL"6| (t All" \rA! ($" E\rAõ (,   Aj6x (t" \rA!  6t (x"Aj6x Alj" : AÞ: B7  6  6 @ Aj" O\r -A?G\rA!@ (ì" M@ !  !  \nAkO\r  Aj" \n \nI"\rM@  j/A¿üF\r@@ Aj! Aj" \rK\r " j/A¿üG\r  !  \nI  Aj"Kq  Atj"(! (!  6ì ( ! @ M\r -A!G\r  j-AßqAÁkAÿqAK\r@ Aj" O\r@  j-AßqAÁkAÿqAK\r Aj" G\r ! A! (ð" K  \nAkOq\r Aj" \n \nI"\rM@  j-A>F\r@@ Aj! Aj" \rK\r " j-A>G\r  !  \nI  Aj" Kq  Atj"(! (!  6ð ( ! @ A j" O\r )B¼ÂìšÄ¨ªÁ… 1Bۅ„BR\rA!\r (ô" K  \nAkOq\r@ Aj" \n \nI" M@  j"/Aݺs -A>srE\r@@ Aj! Aj" K\r  "j"/Aݺs -A>sr\r  !  \nI  \rAj"\rKq@  \rAtj"(! (!  6ô ( !\n ! Aj" \nO\r@ Aj" \nO\r  j-" A0kAÿqA\nIA AßqAÁkAÿqAI E\r@  j-"A0kAÿqA\nI\r AßqAÁkAÿqAI\r A+k"AK\r AF\r Aj" \nF\r@  kA K\r  j-" A:F@  \nO\r@  j-" A k"AMAA tA€€q\r A>G@ A I\r AG\r  j-A-F\rAð! Aj !@@ (x" (|"N@ AÀ Av j AL"6| (t All"\rA! ($" E\r\rAõ (,  \r Aj6x (t"\rA! 6t (x"Aj6x  Alj" Ar: A<: B7  6  6@@ (x" (|"N@ AÀ Av j AL"6| (t All"\rA! ($" E\r\rAõ (,  \r Aj6x (t"\rA! 6t (x"Aj6x  Alj" Ar: A>: B7  6  Ak6 (t (x"Alj"A k Ak6 Ak Ak6 ! !   6 @@@ (x" (|"N@ AÀ Av j AL"6| (t All"E\r 6t (x"Aj6x  Aj6x (t"E\r  Alj"A¼(; B7  6  6@ (x" (|"N@ AÀ Av j AL"6| (t All"E\r 6t (x"Aj6x  Aj6x (t"E\r ( !  Alj"A¾0; B7  6  6 (t (x"Alj"A k Ak6 Ak Ak6A! !  (M\r@@   jAv"Atj"( K@ E@ !   AtjAk(K@ ! Ak!  ( O@ ! \n Aj!  M\r A!  ($"E\rAõ (,  A!  Aj!  A F\r A F\r A\rkA}K\r AÿG AúKq A!kAI A:kAIr AÛkAIrr "! As AßFq! @  \nF\rA!A!@  \nj" ( \nk"A4"AÿM@ A F\r A F\r A kAO\r  @@@  jAm"AtA j(" Au j"AtA j(Aÿÿÿq K@ Ak!   AvAq j"AtA j(AÿÿÿqM\r Aj!  N\r  AN\r A!Aä!AAA  A4"AÿM@ AÿG AúKq A!kAI A:kAIr AÛkAIrr  @@@  jAm"AtA°9j(" Au j"AtA°9j(Aÿÿÿq K@ Ak!   AvAq j"AtA°9j(AÿÿÿqM\r Aj!  N\r A! AN "Aq As qAq"!A  ! ! \n!  rE\r  kAp!@@ (x" (|"N@ AÀ Av j AL"6| (t All"\rA! ($" E\rAõ (,   Aj6x (t"\rA!  6t (x"Aj6x  Alj" AtA# AG  LqAA  NA AJr" AFrA@k:  : B7  \n6  6 \n \r"M\r@@@ (x" (|"N@ AÀ Av j AL"6| (t All"\rA! ($" E\rAõ (,   Aj6x (t"\rA!  6t (x"Aj6x  Alj"AÄ; B7  \r6  \r6 \rAj"\r \nI\r ! \n! @@ (x" (|"N@ AÀ Av j AL"6| (t All"\rA! ($" E\rAõ (,   Aj6x (t"\rA!  6t (x" Aj6x (!  Alj"Aÿ ; B7  6  6A! Aj$@ " \r A (xAÏAJ@ (à"AN@ Ak!\r A€j! AØj! A j!@ (t" Al"j" (! @ -"AÄF\r ( !A! A! AN@   Alj" ( Alj! Al! (! -A q@ A!: Ak"6A!!  j!  I@ ( I\r  I@ ( I\r @  I@ A!G\r  AÛG\r ( A€€ÀqE\r (" (O\r ( j-AÞG\r Aj"6 (t j"(" M\r  ( j  kK"E\r ( "E@ (pAj"6p  6  (Aj6 6 (6 -A”r:  -A˜r: (! (! (  @@@@ -\rA qE\r -AÛG\r E\r (" ("kAG\r -AÛG\r E\r ( ("kAG\r -AÝG\r  AkG\r ( ("kAG\r  (AjG\r@@ Aj" N"@ !  (t! !@@  Alj"\n-"AÄF\r AüF\r \n( kAäK\r \n-AqE\r \n( ! Aj" H\r A!\n \n  \n(" F\r  kAäK\r  I@ (!@@  j-A\nk Aj" G\r A!@   Atj"("L@ (t! @ Alj( " N\r  6  ("L@ (t! @ Alj( " N\r  6 Aj"AG\r \n@@ \n( (I@@  L\r  kAk! (t! A!  AsjAq"@@ AljAÄ; Aj! Aj" G\r AI\r@ Alj"AÄ;L AÄ;8 AÄ;$ AÄ; Aj" G\r \n \n-Ar: \n(6  @ \r  kAk! (t! A!  AsjAq"@@ AljAÄ; Aj! Aj" G\r AI\r@ Alj"AÄ;L AÄ;8 AÄ;$ AÄ; Aj" G\r  \n(6 (6  (6 (t" j" 6 j" 6  -Ar: -Ar: (! (!  Aj L (  (6  (6 (t" j" 6 j" 6  -Ar: -Ar: (! (! (  \r (!  (" ("G\r ( AjK@ -AÀq\r    ( AjM  -AÀq\r   (  AjM "AH\r E\r  (6 (t Alj(!  @  ("O\r (" j-A(G\r Aj!\nA! \r!@@@   jAv"Atj"( K@ E\r  AtjAk( I\r Ak!   (M\r Aj!  O\r A! @@ Aj"  Atj(" I@@  j-A k"AK\rA tA€€qE\r Aj" G\r !  6@  O\r  j-A\nk Aj" O\r  Atj(!  6 @  O\r  j-A)G\rA! A6 B7  6  6 Aj! A    Atj"(" Aj Aj 5E\r@   k ( Aj A j A,j A(j A$j6@ ( " j! (," F!   j"Atj(! (!   ("6(  6$A!A! @  I@@  j-"A k"AK\rA tA€€qE\r Aj" G\r Aj" O\r   Atj("j-! AÿqA)G\r  Aj" 6 ($" (("M@A! A6 B7A   k! @ A6  6   j"6A  @ j"@  Atj!A! !@   Atj("  K" KA!  "kAq"@@  ( j-: Aj! Aj! Aj" G\r  kA|M@@  ( j-:  ( j-:  ( j-:  ( j-: Aj! Aj" G\r   O\r A\n: Aj!  Aj"Atj(! ($" E\rAä (,   A6  6   k6 (! A ! (x" \nL@  6  (t! \n!@  Alj"(K@@ -AqAG\r  ( "Alj( I\r \r k  Aj" H\r  6  \nL\r  kAk! (t! A!  AsjAq"@@ \nAljAÄ; \nAj!\n Aj" G\r AI\r@ \nAlj"AÄ; AÄ;L AÄ;8 AÄ;$ \nAj"\n G\r  -AÀq\r   ( ( AjM"AH\r E\r -Ar:  -Ar: Aj" (tj (6 (t j ( 6  (tj (6( Aj! (t! (@  Alj (Ð6 6Ð  Alj (6 (! (! -!  Aj L   AÛF"!   !   !   ! ! / AŒqE\r@@ "Aj! -$"AÄG" \r  I\r À! !@@ "Ak! \r  K\r -%" AqE\r E\r ( (G\rA‡ APE\r (  (tkAmG\r Ak( (G\r AÄ:$  Aïq:% AkAÄ: Ak" -Aïq: "AN\r B7à A6¸ @A! A6Ô (x"AL\r (t! A!@@ Alj"-"Aq\r -AüG\r ( (kAG\r A6  Ar:@ (ØAH@ 6Ø  (ÜAlj 6 6Ü Aj"6Ô Aj" G\r A!  A! A (xL  A! A0j$ Þ#Aðk"$ B7h B7` B7X B7P B7H B7@ B78 B70 A6( B7 B7 B7 B7A! @    Aj AÐj9\r  A Aj A0j9\r  6( (,! @  Aj (" E@A!  ($"E\rAÒ (,    Aj (" E@A!  ($"E\rAö (,  (`@ (Pk (Tk (Xk (@@ (0k (4k (8k Aðj$ Ý@ ( " ("I@ (!  ( Av jA "At"l"E@A ($"E\rAõ (, A  6 ( Ajl"E@A ($"E\rAõ (, A  6  6 ( ! ( Atj 6  ( Atj 6  ( Aj6 A Ü Aj!@@@ Aj" O\r j-A#G\r j-A rAøG\r !@@@@ j-"A0kAÿqA\nI\r AÁkAÿqAI\r  kAK\r AákAÿqAI\r   kAK\r Aj" G\r !  F\r  kAI\r  @ Aj" O"\r j-A#G\r !@@  kAK\r j-A0kAÿqA K\r Aj" G\r !  F\r  kAI\r   M\r j-AßqAÁkAÿqAK\r  \r@@ j-"AßqAÁkAÿqAO@   kA0K\r A0kAÿqA\nI\r    kA0M\r   Aj" G\r  " kAkA.K\r  M\r j-A;G\rA!  Aj6  ³#Ak"$@@  O\r (!@  j-A k"AK\rA tA€€qE\r Aj" G\r !   O\r (!@  jAk-A k"AK\rA tA€€qE\r Ak" K\r !  6  6  6@  Aj (, ("@ ($"E\rAš (,   AjA<"\r  Aj (, ("E@A!  ($"E\rA¿ (,  Aj$  à!#A0k"\r$  H@ A¸j! A€j! \rAr! \rAr! (!@@ (t" Al" j" -"Aq@ AqE\r@ E\r ,"E\r  [\r ( !  ,"\nAÿq"E\r  \n[E\r (" I\r@@@@@@@@@@@@@@@@@ A!k^  (! Aq@ AN@  Alj" -AÀr: 6  6  AH\r  Alj"( 6¸  6 6@ (ä" AN@  Alj 6  6à 6ä A6  Aj" (xN\r  Alj"-A;G\r (  (" \rHE\r 6  6 Ar:  -Ar: 6  AqE\r \r A€A˜ \nA*Fj" A j6 AÀq"AÀF@A!   \r Aj6 A€F\rA!  Aj6A! A°A´ ( kAFj!\n@ AqE\rA! \n("AH\r@   Atj"\n("L@@  Alj( " N\r \n 6  \n("L@@  Alj( " N\r \n 6 Aj" AG\r  Alj" 6 6  -Ar: -Ar: \r AqE\r \n(6 \n 6 @ AqE\rA! (Ä"AH\r@   Atj"\n("L@@  Alj( " N\r \n 6  \n("L@@  Alj( " N\r \n 6 Aj" AG\r  Alj" 6 6  -Ar: -Ar: AqE\r (Ä6 6Ä @ AqE\r (¼"AH\rA!  Alj" ( (k ( kG\r@   Atj"\n("L@@  Alj( " N\r \n 6  \n("L@@  Alj( " N\r \n 6 Aj" AG\r @ Aj" N\r  kAk!A!  AsjAq"\n@@  AljAÄ; Aj! Aj" \nG\r AI\r@  Alj" AÄ;L AÄ;8 AÄ;$ AÄ; Aj" G\r 6 6 -Ar: -Ar: A6¼ AqE\r\n (¼6 6¼ \n  Aj"Al"j"(! (! \r 6 \r ("6, \r 6( \r 6$ \nAÀF@   \rAAAA¨ \rA(jOAL\r\n \r(!  O\r N"AÿM\rA!A!@@@  jAm" AtA j("Au j"AtA j(Aÿÿÿq K@ Ak!   AvAq j"AtA j(AÿÿÿqM\r Aj!  N\r  AN\r  ( kAG\r@ AqE\rA! (À"AH\r@   Atj"\n("L@@  Alj( " N\r \n 6  \n("L@@  Alj( " N\r \n 6 Aj" AG\r  Alj" 6 6  -Ar: -Ar: AqE\r (À6 6À  ( kAG\r@ AqE\rA! (È"AH\r@   Atj"\n("L@@  Alj( " N\r \n 6  \n("L@@  Alj( " N\r \n 6 Aj" AG\r  Alj" 6 6  -Ar: -Ar:  AqE\r (È6 6È  ( kAG\r@ AqE\rA! (Ì"AH\r@   Atj"\n("L@@  Alj( " N\r \n 6  \n("L@@  Alj( " N\r \n 6 Aj" AG\r  Alj" 6 6  -Ar: -Ar:  AqE\r (Ì6 6Ì  A!A!  A F\r A F\r A kAI\r ( jAk,"@Aó AP\r \r((" I\r Ak!@@@ -AÄF\r ( K\r  (O\r -" Aq\r Ak" O\r  AqE\r   \rA,jAA.AAè \rA$jOAH\r \r(,!@ \nAÀF\r@  O\r (" j-A/G\r Aj  \rA,jAA/A‰A \rA$jOAH\r \r(," O\r  j-A/G\r \r Aj"6, @  O\r ( j-A?G\r Aj  \rA,jAA&AƒA¥ \rA$jOAH\r \r(,!  O\r ( j-A#G\r Aj  \rA,jAAAAë \rA$jOAH\r \r(,! @  O\rA!A!@ ( j" ( kA4"AÿM@ A F\r A F\r A kAO\r  @@@  jAm" AtA j("Au j"AtA j(Aÿÿÿq K@ Ak!   AvAq j"AtA j(AÿÿÿqM\r Aj!  N\r  AN\r ,"@A± A P\r \r($"  (xAlj"O\r@@@ -AÄF\r ( M\r ( K\r -"Aq\r Aj" I\r  AqE\r 6 6  \n:  6  6 (t" j" 6  j" 6  -Ar:  -Ar:  \r Atr 6 A q! Aj! AàqAàG@ \r Atj Aj6 Aj! As AGqE@ \r Atj Aj6 Aj! Aq! Aq!A!A!A! A!@@ \r Atj"(("AH\r  Alj! @ ( (M\r ! ! @ (("AH\r  Alj! @ ( (M\r ! ! Aj! Aj" G\r @ E\r \r Atj((" AH\r  Alj! @ ( (M\r ! ! E\r (! (! (! !\n@@@@@@  Alj"-"A!k\n AÛk A€A˜ A*Fj -"AtAuA qj!\n@ AvAk \nAj!\n  A°A´ ( (kAFj!\n  \nAj!\n @  k"  k" K@  (" (k k j"Al"j" (6  )7  )7   k" 6  6 (t j \n(6 \n 6   O\r  Alj j" (6  )7  )7  k j"6  6 A!\n@   \nAtj"("L@@ AN@  (t Alj( "6  N\r \nAj"\nAG\r (t" Alj" 6  j" 6  -Ar:  -Ar:  AqE\r A€A˜ \nA*Fj AtAuA qj!@@@ AvAk Aj!  Aj! (6  6 -"AqE\r Aq@ (t ( Alj(!  (! Aj" H\r \rA0j$ –#Ak"$@ (E\r  3! (  (pAtj("E@A!  @  ("I\r   ( (ljO\r  (F@ ( (  AE\r A!   6  6  6  Aj6 Aj!@ ("@@   Av"Atj"D"AH@   E\r Aj!  Asj "\r A! E@A!  (! Aj$  ý#A k"$ Aß: A¦Ô;A! ( "A€ q@ A$:A! A€€€q@ Aj rA=: Aj! A€€€q@ Aj rA+: Aj! A€€q@ Aj jAü: Aj! A€€q@ Aj jAÞ: Aj! A€„q@ Aj jAþ: Aj! A! Aj jA:    AjAJ ( "AŒq@ Aq@ AÀ:A! Aq@  rA:: Aj! A€q  rA.: Aj  rA:     AjJ A€jAÿAÐü A j$ ‰ (TE@A Ak! Ak!AA ("\n j-A!F j!A!@@   jAv"Atj" ( K@ E\r  AtjAk( I\r Ak!   (M\r Aj!  @  (M" E@@  kj"@ !@  Atj("  K" KA!  "kAq"\n@@  ( j-: Aj! Aj! Aj" \nG\r  kA|M@@  ( j-:  ( j-:  ( j-:  ( j-: Aj! Aj" G\r   O\r A : Aj! Aj" Atj(! A! ($"E\rAä (, A  k   \nj!  k ! A  Aj60A! Aj !\nA!@@ \n("E\r Aj i"AH\r   kK\r \nAj!\n  j" I\r A=! AH\r A \r  e E@A!  A! (0!\n@ \n(" E\r Aj i" j" K\r Aj a \nAj!\n  K\r A \r  A€Àse \r   \rH!   AHq\r A=! +0 \r   f"AN\r \n -!\n Aj! \r E\rA!@  Atj("\n@  Atj \n cA! Aj"A\nG\r A\nO@A! \n @  Atj(\rA! Aj"A\nG\r A!   :\'A! ! !   k"  H" AÿÿÿÿsJ\rA=! \r  j"  \rH" \nK\r A   e  a A0   A€€se A0  Ae a A   A€Àse ( Ak" O\r B€”ëÜT\r Ak" > @ "I@ Ak"(E\r (¬ k"6¬ ! AJ\r AH@ AjA nAj! AæF!@A A k" A O!\n@  M@AA (!  A€”ëÜ \nv!\rA \ntAs!A! !@  (" \nv j6  q \rl! Aj" I\r AA (! E\r  6 Aj! (¬ \nj"6¬   j" " Atj   kAu J! AH\r A!@  M\r  kAuA l!A\n! ("A\nI\r@ Aj!  A\nl"O\r A AæGk AçF AGqk"  kAuA lA kH@ A„`Aìc AHj A€Èj"A m"\rAtj!\nA\n!  \rA lk"AL@@ A\nl! Aj"AG\r @ \n("  n" lk"\rE \nAj" Fq\r@ AqE@D@C! A€”ëÜG\r \nO\r \nAk-AqE\r D@C! Dà?Dð?Dø?  FDø? \r Av"F \r I!@ \r -A-G\r š! š! \n  \rk"6    a\r \n  j"6 A€”ëÜO@@ \nA6 \nAk"\nK@ Ak" A6 \n \n(Aj"6 Aÿ“ëÜK\r  kAuA l!A\n! ("A\nI\r@ Aj!  A\nl"O\r \nAj"   K! @ " M"E@ Ak"(E\r @ AçG@ Aq!\r  AsA A " J A{Jq"\n j! AA~ \n j! Aq"\r\rAw!@ \r Ak("\nE\rA\n!A! \nA\np\r@ "\rAj! \n A\nl"pE\r \rAs!  kAuA l! A_qAÆF@A!\r  jA k"A AJ"  J!  A!\r  j jA k"A AJ"  J! A!\n AýÿÿÿAþÿÿÿ \rr"J\r AGjAj!@ A_q"AÆF@  AÿÿÿÿsJ\r A AJ!    Au"s k­ d"kAL@@ Ak"A0:  kAH\r Ak" : AkA-A+ AH:  k" AÿÿÿÿsJ\r  j" AÿÿÿÿsJ\r A   j" e  a A0   A€€se@@@ AÆF@ AjA r!  K"! @ 5 d!@  G@  AjM\r@ Ak"A0:  AjK\r   G\r Ak"A0:   ka Aj" M\r @ A‰Aa  M\r AL\r@ 5 d" AjK@@ Ak"A0:  AjK\r A A Na A k! Aj" O\r A J! ! \r  @ AH\r  Aj  K!\n AjA r! !@  5 d"F@ Ak"A0: @  G@  AjM\r@ Ak"A0:  AjK\r  Aa Aj! \rrE\r A‰Aa   k"  Ha k! Aj" \nO\r AN\r A0 AjAAe   ka  ! A0 A jA Ae A   A€Àse    J!\n   AtAuA qj!@ A K\r -!Dð?!@A4 Atk"A€N@Dà! AÿI@ Aÿk!  Dð!Aý  AýOAþk!  AxJ\rD`! A¸pK@ AÉj!  D!Aðh  AðhMA’j!  Aÿj­B4†¿¢! A-F@  š ¡ š!     ¡!  (¬" Au"s k­ d"F@ Ak"A0: (¬! Ar! A q! Ak"\r Aj: AkA-A+ AH: AqE ALq! Aj!@ " ü"AÀÐj- r:  ·¡D0@¢!@ Aj" AjkAG\r Da q\r A.: Aj! Db\r A!\n Aûÿÿÿ   \rk" jkJ\r A  Aj  Ajk" Ak H  " jj" e  a A0   A€€se Aj a A0  kAAe \r a A   A€Àse    J!\n A°j$ \n ¹~  (AjAxq"Aj6 )! )!#A k"$ Bÿÿÿÿÿÿ?ƒ!~ B0ˆBÿÿƒ"§"AøkAýM@ B† B<ˆ„! A€øk­!@ Bÿÿÿÿÿÿÿÿƒ"B€€€€€€€Z@ B|!  B€€€€€€€€R\r Bƒ |! B  BÿÿÿÿÿÿÿV"! ­ |  @  „P\r BÿÿR\r B† B<ˆ„B€€€€€€€„!Bÿ  Aþ‡K@B!Bÿ  A€øAø P"\n" k" AðJ@B!B   B€€€€€€À„ \n!A!\n G@ Aj! ! !@A€ k"AÀq@  A@j­†!B!  E\r  ­"† AÀ k­ˆ„!  †! 7 7 ) )„BR!\n @ AÀq@  A@j­ˆ!B!  E\r AÀ k­†  ­"ˆ„!  ˆ!  7  7 )B† )"B<ˆ„!@ \n­ Bÿÿÿÿÿÿÿÿƒ„"B€€€€€€€Z@ B|!  B€€€€€€€€R\r Bƒ |! B€€€€€€€…  BÿÿÿÿÿÿÿV"! ­ ! A j$ B€€€€€€€€€ƒ B4†„ „¿9 ¦ (T"(! (" ( ("k"  I"@   Q  ( j"6  ( k"6    K"@   Q  ( j"6  ( k6 A: (,"6 6  ¢ E@A @  AÿM\r@AÔÚ((E@ A€qA€¿F\rAèÛA6  AÿM@ A?qA€r: AvAÀr:A  A€@qA€ÀG A€°OqE@ A?qA€r: A vAàr: AvA?qA€r:A  A€€kAÿÿ?M@ A?qA€r: AvAðr: AvA?qA€r: A vA?qA€r:A  AèÛA6 AA  :A Ñ( #Ak"\n$@@@@@@@@@@ AôM@A¤Ü("A A jAøq A I"Av"v"Aq@@ AsAq j"At"AÌÜj" (Ô\\"("F@A¤Ü A~ wq6   6 6 Aj!  Ar6  j" (Ar6 A¬Ü("M\r @@ tA t"A krqh"At"AÌÜj" (Ô\\"("F@A¤Ü A~ wq"6   6  6 Ar6 j"  k"Ar6 j 6 @ AxqAÌÜj!A¸Ü(! A Avt"qE@A¤Ü  r6   ( !  6  6  6  6 Aj!A¸Ü 6A¬Ü 6 A¨Ü(" E\r hAt(Ô^"(Axq k! !@@ ("E@ ("E\r (Axq k"   K"!  ! !  (!  ( "G@ (" 6 6 \n (" Aj ("E\r Aj !@ ! "Aj! ("\r Aj! ("\r A6 A! A¿K\r A j"Axq!A¨Ü(" E\rA! AôÿÿM@ A& Avg"kvAq AtkA>j! A k!@@@ At(Ô^"E@A!  A! A AvkA AGt!@@ (Axq k" O\r ! "\rA! !  ("   AvAqj("F ! At! "\r rE@A!A t"A kr q"E\r hAt(Ô^! E\r @ (Axq k" I!   !  ! ("  ( "\r E\r A¬Ü( kO\r (!  ( "G@ (" 6 6  (" Aj ("E\r Aj !@ ! "Aj! ("\r Aj! ("\r A6  A¬Ü("M@A¸Ü(!@ k"AO@  j" Ar6 j 6  Ar6   Ar6 j" (Ar6A!A! A¬Ü 6A¸Ü 6 Aj! A°Ü("I@A°Ü  k"6A¼ÜA¼Ü(" j"6  Ar6 Ar6 Aj! A! A/j"Aüß(@A„à(  AˆàB7A€àB€ €€€€7Aüß \nA jApqAتժs6AàA6AàßA6A€ "j"A k"q" M\rAÜß("@AÔß(" j" M\r  I\r @Aàß-AqE@@@@@A¼Ü("@Aäß!@ (" M@   (jI\r ("\r An"AF\r !A€à("Ak" q@  k  jA kqj!  O\rAÜß("@AÔß(" j" M\r I\r n" G\r   k q"n" ( (jF\r ! AF\r A0j M@ !  A„à("  kjA kq"nAF\r  j! !  AG\r AàßAàß(Ar6 n!An! AF\r AF\r M\r k" A(jM\r AÔßAÔß( j"6AØß( I@AØß 6 @A¼Ü("@Aäß!@  (" ("jF\r ("\r  A´Ü("A ME@A´Ü 6 A!Aèß 6Aäß 6AÄÜA6AÈÜAüß(6AðßA6@ At" AÌÜj"6Ô\\  6Ø\\ Aj"A G\r A°Ü A(k"Ax kAq"k"6A¼Ü  j"6  Ar6 jA(6AÀÜAŒà(6   O\r  I\r ( Aq\r  j6A¼Ü Ax kAq"j"6A°ÜA°Ü( j" k"6  Ar6  jA(6AÀÜAŒà(6  A!  A!  A´Ü( K@A´Ü 6  j!Aäß!@@  ("G@ ("\r  - AqE\r Aäß!@@ (" M@   (j"I\r (!  A°Ü A(k"Ax kAq"k"6A¼Ü  j"6  Ar6 jA(6AÀÜAŒà(6  A\' kAqjA/k" AjI"A6 Aìß)7 Aäß)7Aìß Aj6Aèß 6Aäß 6AðßA6 Aj!@ A6 Aj! Aj!  I\r  F\r  (A~q6   k"Ar6  6 AÿM@ AøqAÌÜj!A¤Ü("A Avt"qE@A¤Ü  r6  ( ! 6  6 A !A  A! AÿÿÿM@ A& Avg"kvAq AtrA>s!  6 B7 AtAÔÞj!@@A¨Ü("A t"qE@A¨Ü  r6  6  6  A AvkA AGt! (!@ "(Axq F\r Av! At!  Aqj"("\r  6  6 A! ! !A  (" 6  6  6A!A!A j 6  j 6 A°Ü(" M\rA°Ü k"6A¼ÜA¼Ü(" j"6  Ar6 Ar6 Aj!  AèÛA06A!  6 ( j6 Ax kAqj" Ar6 Ax kAqj"  j"k!@A¼Ü( F@A¼Ü 6A°ÜA°Ü( j"6  Ar6  A¸Ü( F@A¸Ü 6A¬ÜA¬Ü( j"6  Ar6  j 6  ("AqAF@ Axq! ( !@ AÿM@ (" F@A¤ÜA¤Ü(A~ Avwq6  6  6  (!@  G@ (" 6  6  @ (" Aj ("E\r Aj !@ ! "Aj! ("\r Aj! ("\r A6  A! E\r@ ("At"(Ô^ F@ AÔÞj 6 \rA¨ÜA¨Ü(A~ wq6  @  (F@  6   6 E\r  6 ("@  6  6 ("E\r  6  6  j"(!  j!  A~q6  Ar6  j 6 AÿM@ AøqAÌÜj!A¤Ü("A Avt"qE@A¤Ü  r6   ( !  6  6  6  6  A! AÿÿÿM@ A& Avg"kvAq AtrA>s!  6 B7 AtAÔÞj!@@A¨Ü("A t"qE@A¨Ü r6  6  6  A AvkA AGt! (!@ "(Axq F\r Av! At!  Aqj"("\r  6  6  6  6  (" 6  6 A6  6  6 Aj!  @ E\r@ ("At"(Ô^ F@ AÔÞj 6 \rA¨Ü A~ wq" 6  @  (F@  6   6 E\r 6 ("@ 6  6 ("E\r 6  6 @ AM@   j"Ar6 j" (Ar6   Ar6  j" Ar6  j 6 AÿM@ AøqAÌÜj!A¤Ü("A Avt"qE@A¤Ü  r6  ( ! 6  6  6  6  A! AÿÿÿM@ A& Avg"kvAq AtrA>s!  6 B7 AtAÔÞj!@@ A t"qE@A¨Ü  r6  6  6  A AvkA AGt! (!@ "(Axq F\r Av! At!  Aqj"("\r  6  6  6  6  (" 6  6 A6  6  6 Aj!  @ E\r@ ("At"(Ô^ F@ AÔÞj 6 \rA¨Ü A~ wq6  @  (F@ 6  6 E\r 6 ("@ 6  6 ("E\r 6  6 @ AM@   j"Ar6 j" (Ar6   Ar6  j" Ar6  j 6 @ AxqAÌÜj!A¸Ü(!A Avt" qE@A¤Ü  r6   ( !  6  6 6 6 A¸Ü 6A¬Ü 6 Aj! \nAj$ ‚ @ E\r Ak" Ak("Axq"j!@ Aq\r AqE\r  ("k"A´Ü(I\r j!@@@A¸Ü( G@ ( ! AÿM@  ("G\rA¤ÜA¤Ü(A~ Avwq6  (!  G@ (" 6  6  (" Aj ("E\r Aj !@ ! "Aj! ("\r Aj! ("\r A6  ("AqAG\rA¬Ü 6  A~q6  Ar6  6  6  6  A! E\r@ ("At"(Ô^ F@ AÔÞj 6 \rA¨ÜA¨Ü(A~ wq6  @  (F@  6   6 E\r  6 ("@  6  6 ("E\r  6  6  O\r ("AqE\r@@@@ AqE@A¼Ü( F@A¼Ü 6A°ÜA°Ü( j"6  Ar6 A¸Ü(G\rA¬ÜA6A¸ÜA6 A¸Ü(" F@A¸Ü 6A¬ÜA¬Ü( j"6  Ar6 j 6 Axq j! ( ! AÿM@ (" F@A¤ÜA¤Ü(A~ Avwq6   6  6  (!  G@ (" 6  6  (" Aj ("E\r Aj !@ ! "Aj! ("\r Aj! ("\r A6   A~q6  Ar6 j 6  A! E\r@ ("At"(Ô^ F@ AÔÞj 6 \rA¨ÜA¨Ü(A~ wq6  @  (F@  6   6 E\r  6 ("@  6  6 ("E\r  6  6  Ar6 j 6  G\rA¬Ü 6 AÿM@ AøqAÌÜj!A¤Ü("A Avt"qE@A¤Ü r6   ( !  6 6  6  6 A! AÿÿÿM@ A& Avg"kvAq AtrA>s!  6 B7 AtAÔÞj!@A¨Ü("A t"qE@A¨Ü  r6  6A!A  A AvkA AGt! (!@ "(Axq F\r Av! At!  Aqj"("\r  6A! !A ! !   (" 6  6A!A!A !  j 6  6 j 6AÄÜAÄÜ(Ak"A 6 ‰  E@ j A@O@AèÛA06A A A jAxq A I! Ak"("Axq!@ AqE@ A€I\r Aj M@ !  kA„à(AtM\r A   j!@  O@  k"AI\r   AqrAr6  j" Ar6  (Ar6  m  A¼Ü( F@A°Ü( j" M\r   AqrAr6  j"  k"Ar6A°Ü 6A¼Ü 6  A¸Ü( F@A¬Ü( j" I\r@  k"AO@   AqrAr6  j" Ar6  j" 6  (A~q6   Aq rAr6  j" (Ar6A!A! A¸Ü 6A¬Ü 6  ("Aq\r Axq j"\n I\r \n k! ( !@ AÿM@ (" F@A¤ÜA¤Ü(A~ Avwq6   6  6  (! @  G@ (" 6  6  @ (" Aj ("E\r Aj !@ ! "Aj! ("\r Aj! ("\r A6  A! E\r@ ("At"(Ô^ F@ AÔÞj 6 \rA¨ÜA¨Ü(A~ wq6  @  (F@ 6  6 E\r  6 ("@  6  6 ("E\r  6  6 AM@  Aq \nrAr6  \nj" (Ar6    AqrAr6  j" Ar6  \nj" (Ar6  m !  "@ Aj j"E@A  A|Ax Ak("Aq Axqj"   KQ k  «  j!@@ ("Aq\r AqE\r (" j!@@@ k"A¸Ü(G@ ( ! AÿM@  ("G\rA¤ÜA¤Ü(A~ Avwq6  (! G@ (" 6  6  (" Aj ("E\r Aj !@ ! "Aj! ("\r Aj! ("\r A6  ("AqAG\rA¬Ü 6  A~q6 Ar6  6  6  6  A! E\r@ ("At"(Ô^ F@ AÔÞj 6 \rA¨ÜA¨Ü(A~ wq6  @ (F@  6   6 E\r  6 ("@  6  6 ("E\r  6  6 @@@@ ("AqE@A¼Ü( F@A¼Ü 6A°ÜA°Ü( j"6 Ar6 A¸Ü(G\rA¬ÜA6A¸ÜA6 A¸Ü(" F@A¸Ü 6A¬ÜA¬Ü( j"6 Ar6 j 6 Axq j! ( ! AÿM@ (" F@A¤ÜA¤Ü(A~ Avwq6   6  6  (!  G@ (" 6  6  (" Aj ("E\r Aj !@ ! "Aj! ("\r Aj! ("\r A6   A~q6 Ar6 j 6  A! E\r@ ("At"(Ô^ F@ AÔÞj 6 \rA¨ÜA¨Ü(A~ wq6  @  (F@  6   6 E\r  6 ("@  6  6 ("E\r  6  6 Ar6 j 6 G\rA¬Ü 6 AÿM@ AøqAÌÜj!A¤Ü("A Avt"qE@A¤Ü  r6   ( !  6  6 6 6 A! AÿÿÿM@ A& Avg"kvAq AtrA>s! 6 B7 AtAÔÞj!@@A¨Ü("A t"qE@A¨Ü  r6  6 6  A AvkA AGt! (!@ "(Axq F\r Av! At!  Aqj"("\r  6 6 6 6 (" 6  6 A6 6 6 W~@ ­B|BøÿÿÿƒAØÚ("­|"BÿÿÿÿX@ §"?AtM\r \r AèÛA06A AØÚ 6 ß  #Ak"$  6 @ AÓM@AÐÐAÒ A jp(!  A|O@]  AÒn"AÒl"k6AÒAÐÓ Ajp"( j! AÒkAu!@A! !@@@ ! A/F@AÓ!@ n" I\r  lF\r A\nj"n" I\r  lF\r A j"n" I\r  lF\r Aj"n" I\r  lF\r Aj"n" I\r  lF\r Aj"n" I\r  lF\r Aj"n" I\r  lF\r Aj"n" I\r  lF\r A$j"n" I\r  lF\r A(j"n" I\r  lF\r A*j"n" I\r  lF\r A.j"n" I\r  lF\r A4j"n" I\r  lF\r A:j"n" I\r  lF\r AA AM!@@ j"\rA”à("E\r \n  "E@u ]  \\w ¬@  (AÿÿÿÿqAkA\n , "AH"" (  "kM@ E\r ( AH! @  j  ü\n  j!@ , AH@ 6  Aÿq:  jA:   j k  A  x …Aöÿÿÿ k O@A÷ÿÿÿ! ( , AH! AòÿÿÿM@A  j" At"  K"ArAj A I! t!@ E\r E\r  ü\n @ E\r E\r  j  ü\n   j"k!\n@  F\r \nE\r  j j  j j \nü\n A\nG@ k 6 A€€€€xr6  j \nj"6  jA: u Å@@@ , "AN@A\n! A\nF\r AjAÿq:  (" (AÿÿÿÿqAk"G\r !@ AöÿÿÿG@A÷ÿÿÿ! ( , AH! AòÿÿÿM@A Aj" At"  K"ArAj A I! t!@ E\r E\r   ü\n @  F\r  k"E\r  j  j ü\n A\nG@ k 6 A€€€€xr6  u 6 ! Aj6 (! j"A: : « A÷ÿÿÿI@ (AÿÿÿÿqAkA\n , "AH" I@A ArAj A I"t! (!@ (  "Aj"E\r E\r   AH ü\n AH@ k 6 6 A€€€€xr6  u h (Aÿÿÿÿq" K@ 6 (!@ E\r E\r   ü\n  jA: Ak  kAj ("A   x Q A\nM@ : @ E\r E\r  ü\n jA: A\n A\nk - Aÿq"A  x #A k"$#Ak"$ Aj" A j" Aj"k"A L@A= A ArgkAÑ lA v"  At(°TIkAjH\r  A¿„=M@ AÎM@ AãM@ A M@  A0r: Aj   At/àT; Aj  AçM@  AÿÿqAän"A0r:   AälkAÿÿqAt/àT; Aj   ~  AŸM@  AÎn"A0j: Aj  AÎlk~     AÿÁ×/M@ Aÿ¬âM@  AÀ„=n"A0j: Aj  AÀ„=lk   €  Aÿ“ëÜM@  A€Â×/n"A0j: Aj  A€Â×/lk€   A€Â×/n"At/àT; Aj  A€Â×/lk€ !A 6  6 A j" (6  ( 6 Aj$@ ( " Aj"k"A÷ÿÿÿI@@ A\nM@ :  Ar"Ajt! Aÿÿÿÿk6 6 6 !  k!@  F\r E\r  ü\n jA:  u A j$ 2 Aän"At/àT;  AälkAt/àT; Aj * AÎn"At/àT; Aj  AÎlk~ * AÀ„=n"At/àT; Aj  AÀ„=lk  AÐjjAÐj  t E@ ( (F F@A ("-!@ ("-"E\r G\r@ -! -"E\r Aj! Aj! F\r F Ú#AÐk"$@A ( (F\r#A@j"$  ("Ak("j!@ Ak("(AÜÖ(F@A  !   "L@ B7 A6 AØÖ6  6  6 B7 B7$ B7, A6< B€€€€€€€74  Aj  AA (( (\r B7 A6 A¨Ö6  6 AØÖ6 B7 B7$ B7, B73 A6< A:;  Aj AA (( A!@@ (( (A ($AFA ( AFA (,AF!  (AG@ (,\r ( AG\r ($AG\r (! A@k$A "E\r ("E\r AjAA8ü A:K A6  6  6 A6D  Aj A (( (,"AF@  ($6 AF ! AÐj$  A6 Aç6 AŽ 6] v ($"E@ 6 6 A6$ (86 @@ ( (8G\r ( G\r (AG\r 6 A:6 A6 Aj6$  ( ((F@   … 5 ( ((F@   … ("    (( { ("Aq! -7AF@ Au" E\r ( j(  Au E\r  ((68A!A ! ("   j A Aq (( r ( ((F@   … ( ! Aj"   ˆ@ AI\r  Atj! Aj!@   ˆ -6\r Aj" I\r š A:5@  (G\r A:4@ ("E@ A6$ 6 6 AG\r (0AF\r   F@ ("AF@ 6 ! (0AG\r AF\r  ($Aj6$ A:6 Â@ ( ƒ@  (G\r (AF\r  6 @ ( ƒ@@ ( G@  (G\r AG\r A6   6 (,AF\r Aj" ( Atj!@@@ @  M\r A;4    A Œ -6\r -5AG\r -4AF@ (AF\rA!A! -AqE\r  A! -Aq\rA  AA Aq 6, \r  A6,  Aj! ( ! Aj"     AI\r  Atj! Aj!@ ("AqE@ ($AG\r @ -6\r      Aj" I\r  AqE@@ -6\r ($AF\r      Aj" I\r  @ -6\r ($AF@ (AF\r      Aj" I\r   6  ((Aj6( ($AG\r (AG\r A:6 K ("Au! ("   Aq ( j(  j A Aq  (( I ("Au! ("  Aq ( j(  j A Aq  (( Š@ ( ƒ@  (G\r (AF\r  6 ( ƒ@@ ( G@  (G\r AG\r A6   6 @ (,AF\r A;4 ("   A  (( -5AF@ A6, -4E\r  A6,  6  ((Aj6( ($AG\r (AG\r A:6 ("     (( ¦@ ( ƒ@  (G\r (AF\r  6 ( ƒE\r@ ( G@  (G\r AG\r A6   6  6  ((Aj6(@ ($AG\r (AG\r A:6 A6, › ( ƒ@    Š -5! ( ! A:5 -4! A:4 Aj"     Œ  -4"\nr!  -5" r!@ AI\r Atj! Aj!@ -6\r@ \nAq@ (AF\r -Aq\r  AqE\r -AqE\r A;4      Œ -5" rAq! -4"\n rAq! Aj" I\r  Aq:5  Aq:4 9 ( ƒ@    Š ("      ((  ( ƒ@    Š A§ 7 AàÙ6 ("Ak" (Ak"6 AH@ A kk ” k  (  $ # kApq"$ # ‘P(A€ Þ{"type":"Document"},"attributes":{summarytbodyTableBodyLatexMathDisplay\\u%04x-+ 0X0x-0X+0X 0X-0x+0x 0xTableRowdivnavmenuTextUnorderedListOrderedListstartSuperscriptSubscripttfootcountbodyRowCountheadRowCountbasefontDocumentimportantdefaulttightrightHighlightleftframesetfieldsetdt\\taddressdetailsEmphasisnoframes%s:%d: %strvectordirhrfootercenterSpoilerheaderfenceChar\\roptgroupcolgroup/Users/ernest/react-native-enriched-markdown/packages/core/cpp/wasm/ASTSerializer.cpp/emsdk/emscripten/system/lib/libcxxabi/src/private_typeinfo.cpptipcautionoptionfigcaptionAdmonitionsectionmainalignnan\\nformmenuitemListItemparamulurlcolhtmlTableHeaderCellTableCellleveldlisTasklinkLinkCodeBlocktrackSoftBreakLineBreakThematicBreaklibad_array_new_lengthParagraphStrikethroughsearchdialogStrongbasic_stringnodeTypeToStringwarningHeadinginf\\ftrueblockquoteBlockquotenotefalsebasefigureadmonitionTypeUnderlineLatexMathInlineBlankLineiframetitlearticletableTableImageCodeasidetdlegendtaskCheckedddtheadTableHead\\b"\'=<>`-_.-+_\\\\({[,"children":[NANINFcatching a class without an object?)}].!?,;mailto:,"content":h6h5h4h3h2h1http://Too many link reference definition instantiations.Unsupported abi_version.Aborted from text() callback.Aborted from enter_span() callback.Aborted from leave_span() callback.Aborted from enter_block() callback.Aborted from leave_block() callback.malloc() failed.realloc() failed.@:..!#$%&\'*+/=?^_`{|}~-_.:-+-.-_+-_*(null)Suppressing too sparse table (see https://github.com/mity/md4c/issues/345)._=().+-_~%false && "unhandled NodeType in nodeTypeToString"\\"{"type":"[]!xX \nñ<‡í bOFß*$®ŒšŸòT2q¾Îé<Ь¸ùlAè ~€ ¸+Œ ô)NSt3__220__shared_ptr_emplaceIN8Markdown15MarkdownASTNodeENS_9allocatorIS2_EEEE"ƒA€ ¹Nú‡RA  f ° à \rˆ P\rˆ \rð\rˆ ˆ  @`€ˆ ˆ  Àˆ ˆ ˆ ˆ ˆ A ?/A° Äè£\n-Aà dƒµ¯A 5KG[uzÞ9AÐ 50a\nÉ|‘\'A MÝÚ×ÔÑÎO’y¹Að A€ 8$èA  ‚–AÀ \r~XAà ¶¦ZA€ \rP¨A  Tw$AÀ E,5Â9N\nküA ®A  —  € @\n €/ _ 0A@Z€µÀ@րØ@ހ@.€2@6€9@G€J@v€xy@}€‚„†‡‰Š‹Ž‘“”–—˜œŸ @¤€¦§©¬®¯±²³µ·¸¼ÄÅÇÈÊË@Û€Þ@î€ñòôö÷ø@€ "@2€:;=>ACDEF@N€Eprv†ˆ@Š€ŒŽ‘@¡€£@«€ÂÏÐÑÕÖØ@î€ðñôõ÷ùúý@ÿ€@€@/€`@€€Š@¾€ÀÁ@Í€Ð@.€1@V€ @Å€ÇÍø@ý€€‚ƒ„…†‡ˆ‰@º€½@¿€@”€› @þ€@€@€(@/€8@?€H@M€Y[]_h@o€¸¹º»¾È@Ë€ØÙÚÛèéêëìøùúû&!*!+!2!`!@o!€ƒ!¶$@Ï$€,@/,€`,b,c,d,g,@k,€m,n,o,p,r,u,~,,€,@â,€ë,í,ò,@¦@l¦€€¦@š¦€"§@.§€2§@n§€y§{§}§~§@†§€‹§§§’§–§@¨§€ª§«§¬§­§®§°§±§²§³§´§@§€Ä§Å§Æ§Ç§É§Ë§Ì§@Ú§€Ü§Ý§â§õ§l«m«p«@¿«€!ÿ@:ÿ€@\'€°@Ó€p@z€|@Š€Œ@’€”•€ @² €P\r@e\r€ @¿€@n@_n€ n@¸n€@ßHßJßMßQßhß@n߀rß@~߀é@!é€az¼àöøþ/37:HKwÿz~sSƒ…TˆVWŒÝY[’`cih™oru¡¥€¨ƒ­ˆ°Š‹´¶’¹½ÆÆÉÉÌÌÜßïóóõ•¿ùž#3e,<šf,B€‰ŒGO¹qswó¬­¯ÌÍαÁÃËÃײ¸ÆÀÙïºÁ¸µøòû{}P_0Oa‹¿ÏÂÎÑ/a†-%-\'---ðõ24>ABBJcK¦ŠÐúýÿ•a¡ÿ \'07@EQSUW`g°±pq¹ruÐÑvwàáz{åxy|}ÉkåN!p!!„!Ð$é$0,_,a,k}}h,l,QqPRs,v,?@,ã,ì,î,ó,A¦m¦¦›¦#§/§3§o§z§|§y§‡§Œ§e‘§“§—§©§f\\aljž‡S«µ§Ã§”§‚Žȧʧdͧۧ›w|ö§K«L« ïAÿZÿ(OØû—¡£±³¹»¼À ò p\r…\rÀß`nn»nÓnAßIßKßNßRßißoßsßß"éCéAÀ1 Óß0Ið‡–—˜™šžP€@‡€ˆ@€@—€˜@Ÿ€ @§€¨@¯€²³´¶¼ÂÃÄÆÌÖäæòóôöüûûûûûûûûûû•ßA 3 ¥ssi¼nj e‚h1tw\ny\na¾ssʹ¹¹ ¹\'¹ ¹\'¹`¹g¹`¹g¹p¹±¹¬¹±B±¹t¹·¹®¹·B·¹¹BÁÅB|¹É¹Î¹ÉBɹfffiflststtvtetk~vtmssAÐ6 À°RTV·ÇÒÓ×âãç÷ûû¹ÅÅÅÅB±B¹·B¹¹¹¹BÅÅÅBÉB¹ffiffl@.À 5P A¤9 ¬!@/€:@@€[@`€{@~€¡@©€«@¬€®@±€´¶@¸€»¿×÷Â@Å€Ò@߀å@ë€íï@ÿ€u~„@…€‡ö‚Z@_€‰@Š€@€¾ÀÃÆó@ô€@€@€j@m€ÔÞéý@þ€@\r€ö@ù€þ@ÿ€0@>€^ˆd @e €p ò @ó €ú @û €ý v\nð\n@ñ\n€p ó @ú €w  „ O\ry\rô\r?OZ@[€@€@€468:@=€…¾@Å€Ç@Ì€Î@Ú€J@O€ž@Ÿ€û`@h€@™€m@n€›@œ€ë@í€5@6€Ô@Ö€Ø@Û€@\n€@D@E€Þ@ÿ€@€ @¦€¨@­€N@O€Z@j€t@€ü@ÿ€;@?€~@€À@Ç€Ó½¿@Á€Í@Ï€Ý@߀í@ï€ý@þ€ @\' €0 @^ €z @~ €Š @Ž €  @Ä €!@!€!@!€!@ !€!!@!€!@#!€%!\'!)!.!:!@;!€@!@D!€J!@M!€O!Š!@‹!€!@)$€@$@J$€œ$@é$€%@u\'€”\'@s+€v+@ÿ+€å,@ê,€ù,@ü,€þ,@ÿ,€p-.@..€0.@].€`.@c.€€.@™.€›.@ó.€/@Õ/€ð/@ÿ/€0@0€0@ 0€0060@70€=0@?0€›0@œ0€ 0û01@‘1€–1@Ÿ1€À1@å1€ï12@2€*2@G2€P2`2@2€Š2@°2€À2@ÿ3€ÀM@ÿM€¤@Ƥ€þ¤@ÿ¤€\r¦@¦€s¦~¦ò¦@÷¦€§@§€ §@!§€‰§@Ч€(¨@+¨€6¨@9¨€t¨@w¨€Î¨@Ϩ€ø¨@ú¨€ü¨.©@/©€_©Á©@Í©€Þ©@ß©€\\ª@_ª€wª@yª€Þª@ߪ€ðª@ñª€[«j«@k«€ë«)û²û@Òû€>ý@Oý€ý@‘ý€Èý@Ïý€üý@ÿý€þ@þ€0þ@Rþ€Tþ@fþ€hþ@kþ€ÿ@ÿ€ÿ@ ÿ€;ÿ@@ÿ€[ÿ@eÿ€àÿ@æÿ€èÿ@îÿ€üÿ@ýÿ€@€7@?€y@‰€Œ@Ž€@œ€ Ð@ü€ŸÐoWw@x€ ? P\n@X\n€\nÈ\nð\n@ö\n€9 @? €™ @œ €n\rŽ\r@\r€­É@Ê€Ð@Ø€U@Y€†@‰€G@M€»@¼€¾@Á€@@C€t@u€Å@È€ÍÛÝ@߀8@=€©Ô@Õ€×@Ø€K@O€Z@[€]ÆÁ@×€A@C€`@l€¹<@?€;D@F€â?@F€š@œ€ž@¢€@ €áA@E€p@q€÷@ø€C@O€Õ@ñ€ÿp$@t$€ñ/@ò/€nj@oj€õj7k@?k€Dk@Ek€mm@om€—n@šn€âoœ¼Ÿ¼Ì@ïÌ€úÌ@üÌ€Í@³Î€ºÎ@Ð΀ÒÎ@Ô΀ÝÎ@ý΀PÏ@ÃÏ€Ð@õЀÑ@&Ñ€)Ñ@dÑ€jÑ@lÑ€ƒÑ@„Ñ€ŒÑ@©Ñ€®Ñ@AÒ€EÒSÒ@ZÒ€]Ò@^Ò€`Ò@Ò€Ó@VÓ€ÁÖÛÖûÖ×5×O×o׉ש×Ãר@ÿÙ€7Ú@:Ú€mÚ@tÚ€vÚ@ƒÚ€…Ú@‹Ú€Û@Û€Oáÿâÿå^é@_逬ì°ì.íðî@ñî€ð@+ð€0ð@“ð€ ð@®ð€±ð@¿ð€Áð@Ïð€Ñð@õð€\rñ@®ñ€æñ@ò€ò@;ò€@ò@Hò€Pò@Qò€`ò@eò€ó@Ùö€Üö@ìö€ðö@üö€÷@Û÷€à÷@ë÷€ð÷@ ø€ø@Gø€Pø@Yø€`ø@‡ø€ø@­ø€°ø@»ø€Àø@Áø€Ðø@Øø€ù@Wú€`ú@mú€pú@|ú€€ú@Æú€ÈúÌú@Ýú€ßú@ëú€ïú@úú€û@’û€”û@ïû€úû AãÌ  AðÌ A  \n\n\n   AÁÍ ! \r\r  AûÍ  A‡Î  AµÎ AÁÎ  AïÎ AûÎ  A²Ï  AãÏ AïÏ  AÐ A©Ð € 0123456789ABCDEF \r%)+/5;=CGIOSYaegkmqƒ‰‹•—£§­³µ¿ÁÅÇÓ \r%)+/5;=CGIOSYaegkmqyƒ‰‹•—£§©­³µ»¿ÁÅÇѐ+Ø)NSt3__214__shared_countE, *Ð)NSt3__219__shared_weak_countEA´Ô œ\ndè\' †@B€–˜áõʚ;00010203040506070809101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899¸+4+<-N10__cxxabiv116__shim_type_infoE¸+d+(+N10__cxxabiv117__class_type_infoEX+ !"#$%&Ø+\'!"#()*¸+ä+X+N10__cxxabiv120__si_class_type_infoE4,+!"#,-.¸+@,X+N10__cxxabiv121__vmi_class_type_infoE°,/0+„,St9exception¸+ ,|,St9bad_alloc¸+¼,”,St20bad_array_new_lengthì,12¸+ø,|,St11logic_error-32¸+(-ì,St12length_error+D-St9type_infoAÔÚ  . 0€')}function getBinarySync(file){return file}async function getWasmBinary(binaryFile){return getBinarySync(binaryFile)}async function instantiateArrayBuffer(binaryFile,imports){try{var binary=await getWasmBinary(binaryFile);var instance=await WebAssembly.instantiate(binary,imports);return instance}catch(reason){err(`failed to asynchronously prepare wasm: ${reason}`);abort(reason)}}async function instantiateAsync(binary,binaryFile,imports){return instantiateArrayBuffer(binaryFile,imports)}function getWasmImports(){var imports={env:wasmImports,wasi_snapshot_preview1:wasmImports};return imports}async function createWasm(){function receiveInstance(instance){wasmExports=instance.exports;assignWasmExports(wasmExports);updateMemoryViews();return wasmExports}function receiveInstantiationResult(result){return receiveInstance(result["instance"])}var info=getWasmImports();var instantiateWasm=Module["instantiateWasm"];if(instantiateWasm){return new Promise(resolve=>{instantiateWasm(info,inst=>resolve(receiveInstance(inst)))})}wasmBinaryFile??=findWasmBinary();var result=await instantiateAsync(wasmBinary,wasmBinaryFile,info);var exports=receiveInstantiationResult(result);return exports}class ExitStatus{name="ExitStatus";constructor(status){this.message=`Program terminated with exit(${status})`;this.status=status}}var HEAP16;var HEAP32;var HEAP64;var HEAP8;var HEAPF32;var HEAPF64;var HEAPU16;var HEAPU32;var HEAPU64;var HEAPU8;var callRuntimeCallbacks=callbacks=>{while(callbacks.length>0){callbacks.shift()(Module)}};var onPostRuns=[];var onPreRuns=[];var noExitRuntime=true;var stackRestore=val=>__emscripten_stack_restore(val);var stackSave=()=>_emscripten_stack_get_current();var UTF8Decoder=globalThis.TextDecoder&&new TextDecoder;var findStringEnd=(heapOrArray,idx,maxBytesToRead,ignoreNul)=>{var maxIdx=idx+maxBytesToRead;if(ignoreNul)return maxIdx;while(heapOrArray[idx]&&!(idx>=maxIdx))++idx;return idx};var UTF8ArrayToString=(heapOrArray,idx=0,maxBytesToRead,ignoreNul)=>{var endPtr=findStringEnd(heapOrArray,idx,maxBytesToRead,ignoreNul);if(endPtr-idx>16&&heapOrArray.buffer&&UTF8Decoder){return UTF8Decoder.decode(heapOrArray.subarray(idx,endPtr))}var str="";while(idx>10,56320|ch&1023)}}return str};var UTF8ToString=(ptr,maxBytesToRead,ignoreNul)=>ptr?UTF8ArrayToString(HEAPU8,ptr,maxBytesToRead,ignoreNul):"";var ___assert_fail=(condition,filename,line,func)=>abort(`Assertion failed: ${UTF8ToString(condition)}, at: `+[filename?UTF8ToString(filename):"unknown filename",line,func?UTF8ToString(func):"unknown function"]);class ExceptionInfo{constructor(excPtr){this.excPtr=excPtr;this.ptr=excPtr-24}set_type(type){HEAPU32[this.ptr+4>>2]=type}get_type(){return HEAPU32[this.ptr+4>>2]}set_destructor(destructor){HEAPU32[this.ptr+8>>2]=destructor}get_destructor(){return HEAPU32[this.ptr+8>>2]}set_caught(caught){caught=caught?1:0;HEAP8[this.ptr+12]=caught}get_caught(){return HEAP8[this.ptr+12]!=0}set_rethrown(rethrown){rethrown=rethrown?1:0;HEAP8[this.ptr+13]=rethrown}get_rethrown(){return HEAP8[this.ptr+13]!=0}init(type,destructor){this.set_adjusted_ptr(0);this.set_type(type);this.set_destructor(destructor)}set_adjusted_ptr(adjustedPtr){HEAPU32[this.ptr+16>>2]=adjustedPtr}get_adjusted_ptr(){return HEAPU32[this.ptr+16>>2]}}var uncaughtExceptionCount=0;var ___cxa_throw=(ptr,type,destructor)=>{var info=new ExceptionInfo(ptr);info.init(type,destructor);uncaughtExceptionCount++;abort()};var __abort_js=()=>abort("");var getHeapMax=()=>536870912;var alignMemory=(size,alignment)=>Math.ceil(size/alignment)*alignment;var growMemory=size=>{var oldHeapSize=wasmMemory.buffer.byteLength;var pages=(size-oldHeapSize+65535)/65536|0;try{wasmMemory.grow(pages);updateMemoryViews();return 1}catch(e){}};var _emscripten_resize_heap=requestedSize=>{var oldSize=HEAPU8.length;requestedSize>>>=0;var maxHeapSize=getHeapMax();if(requestedSize>maxHeapSize){return false}for(var cutDown=1;cutDown<=4;cutDown*=2){var overGrownHeapSize=oldSize*(1+.2/cutDown);overGrownHeapSize=Math.min(overGrownHeapSize,requestedSize+100663296);var newSize=Math.min(maxHeapSize,alignMemory(Math.max(requestedSize,overGrownHeapSize),65536));var replacement=growMemory(newSize);if(replacement){return true}}return false};var getCFunc=ident=>{var func=Module["_"+ident];return func};var writeArrayToMemory=(array,buffer)=>{HEAP8.set(array,buffer)};var lengthBytesUTF8=str=>{var len=0;for(var i=0;i=55296&&c<=57343){len+=4;++i}else{len+=3}}return len};var stringToUTF8Array=(str,heap,outIdx,maxBytesToWrite)=>{if(!(maxBytesToWrite>0))return 0;var startIdx=outIdx;var endIdx=outIdx+maxBytesToWrite-1;for(var i=0;i=endIdx)break;heap[outIdx++]=u}else if(u<=2047){if(outIdx+1>=endIdx)break;heap[outIdx++]=192|u>>6;heap[outIdx++]=128|u&63}else if(u<=65535){if(outIdx+2>=endIdx)break;heap[outIdx++]=224|u>>12;heap[outIdx++]=128|u>>6&63;heap[outIdx++]=128|u&63}else{if(outIdx+3>=endIdx)break;heap[outIdx++]=240|u>>18;heap[outIdx++]=128|u>>12&63;heap[outIdx++]=128|u>>6&63;heap[outIdx++]=128|u&63;i++}}heap[outIdx]=0;return outIdx-startIdx};var stringToUTF8=(str,outPtr,maxBytesToWrite)=>stringToUTF8Array(str,HEAPU8,outPtr,maxBytesToWrite);var stackAlloc=sz=>__emscripten_stack_alloc(sz);var stringToUTF8OnStack=str=>{var size=lengthBytesUTF8(str)+1;var ret=stackAlloc(size);stringToUTF8(str,ret,size);return ret};var ccall=(ident,returnType,argTypes,args,opts)=>{var toC={string:str=>{var ret=0;if(str!==null&&str!==undefined&&str!==0){ret=stringToUTF8OnStack(str)}return ret},array:arr=>{var ret=stackAlloc(arr.length);writeArrayToMemory(arr,ret);return ret}};function convertReturnValue(ret){if(returnType==="string"){return UTF8ToString(ret)}if(returnType==="boolean")return Boolean(ret);return ret}var func=getCFunc(ident);var cArgs=[];var stack=0;if(args){for(var i=0;i{var numericArgs=!argTypes||argTypes.every(type=>type==="number"||type==="boolean");var numericRet=returnType!=="string";if(numericRet&&numericArgs&&!opts){return getCFunc(ident)}return(...args)=>ccall(ident,returnType,argTypes,args,opts)};{if(Module["noExitRuntime"])noExitRuntime=Module["noExitRuntime"];if(Module["print"])out=Module["print"];if(Module["printErr"])err=Module["printErr"];if(Module["arguments"])programArgs=Module["arguments"];if(Module["thisProgram"])thisProgram=Module["thisProgram"];var preInit=Module["preInit"];if(preInit){if(typeof preInit=="function")Module["preInit"]=preInit=[preInit];while(preInit.length>0){preInit.shift()()}}}Module["ccall"]=ccall;Module["cwrap"]=cwrap;Module["UTF8ToString"]=UTF8ToString;var _parseMarkdown,__emscripten_stack_restore,__emscripten_stack_alloc,_emscripten_stack_get_current,memory,__indirect_function_table,wasmMemory;function assignWasmExports(wasmExports){_parseMarkdown=Module["_parseMarkdown"]=wasmExports["parseMarkdown"];__emscripten_stack_restore=wasmExports["_emscripten_stack_restore"];__emscripten_stack_alloc=wasmExports["_emscripten_stack_alloc"];_emscripten_stack_get_current=wasmExports["emscripten_stack_get_current"];memory=wasmMemory=wasmExports["memory"];__indirect_function_table=wasmExports["__indirect_function_table"]}var wasmImports={__assert_fail:___assert_fail,__cxa_throw:___cxa_throw,_abort_js:__abort_js,emscripten_resize_heap:_emscripten_resize_heap};async function run(){preRun();var setStatus=Module["setStatus"];if(setStatus){setStatus("Running...");await new Promise(resolve=>setTimeout(resolve,1));setTimeout(setStatus,1,"")}if(ABORT)return;initRuntime();Module["onRuntimeInitialized"]?.();postRun()}var wasmExports;wasmExports=await createWasm();await run(); -;return Module}})();if(typeof exports==="object"&&typeof module==="object"){module.exports=createMd4cModule;module.exports.default=createMd4cModule}else if(typeof define==="function"&&define["amd"])define([],()=>createMd4cModule); -+var createMd4cModule=(()=>{var _scriptName=globalThis.document?.currentScript?.src;return async function(moduleArg={}){var moduleRtn;var Module=moduleArg;var ENVIRONMENT_IS_WEB=true;var ENVIRONMENT_IS_WORKER=false;var arguments_=[];var thisProgram="./this.program";var scriptDirectory="";var readAsync;if(ENVIRONMENT_IS_WEB||ENVIRONMENT_IS_WORKER){try{scriptDirectory=new URL(".",_scriptName).href}catch{}{readAsync=async url=>{var response=await fetch(url,{credentials:"same-origin"});if(response.ok){return response.arrayBuffer()}throw new Error(response.status+" : "+response.url)}}}else{}var out=console.log.bind(console);var err=console.error.bind(console);var wasmBinary;var ABORT=false;function binaryDecode(bin){for(var i=0,l=bin.length,o=new Uint8Array(l),c;i>8&c}return o}var readyPromiseResolve,readyPromiseReject;var HEAP8,HEAPU8,HEAP16,HEAPU16,HEAP32,HEAPU32,HEAPF32,HEAPF64;var HEAP64,HEAPU64;var runtimeInitialized=false;function updateMemoryViews(){var b=wasmMemory.buffer;HEAP8=new Int8Array(b);HEAP16=new Int16Array(b);HEAPU8=new Uint8Array(b);HEAPU16=new Uint16Array(b);HEAP32=new Int32Array(b);HEAPU32=new Uint32Array(b);HEAPF32=new Float32Array(b);HEAPF64=new Float64Array(b);HEAP64=new BigInt64Array(b);HEAPU64=new BigUint64Array(b)}function preRun(){if(Module["preRun"]){if(typeof Module["preRun"]=="function")Module["preRun"]=[Module["preRun"]];while(Module["preRun"].length){addOnPreRun(Module["preRun"].shift())}}callRuntimeCallbacks(onPreRuns)}function initRuntime(){runtimeInitialized=true;wasmExports["__wasm_call_ctors"]()}function postRun(){if(Module["postRun"]){if(typeof Module["postRun"]=="function")Module["postRun"]=[Module["postRun"]];while(Module["postRun"].length){addOnPostRun(Module["postRun"].shift())}}callRuntimeCallbacks(onPostRuns)}function abort(what){Module["onAbort"]?.(what);what="Aborted("+what+")";err(what);ABORT=true;what+=". Build with -sASSERTIONS for more info.";var e=new WebAssembly.RuntimeError(what);readyPromiseReject?.(e);throw e}var wasmBinaryFile;function findWasmBinary(){return binaryDecode('asm«````````````` `````||`~`|``Tenv __cxa_throwenv\r__assert_failenvemscripten_resize_heapenv _abort_js ¾¼   \r\r    \r\n     \n\n\n\np99€€@ Aã€ ¢memory__wasm_call_ctors\rparseMarkdown__indirect_function_table_emscripten_stack_restore½_emscripten_stack_alloc¾emscripten_stack_get_current¿ PA 8º \r{ !"#$%&\'()*+,~-E@G_mno{-cc¦¶³¨-µ²©-´¯¬-¸-¹-·»¼»» (\n¼è¼ AÈÜB7AÐÜA6AßÜA:AÔÜAµ(6AØÜA¹-:AÙÜA:AëÜA:AàÜAŽ/;AâÜA-:AãÜA:A÷ÜA:AìÜAç(6AðÜAë-:AñÜA:AƒÝA :AøÜA¯ )7A€ÝA· -:AÝA:AˆÝB칻֮سå7A“ÝA:AÝA:AŸÝA:A”ÝA¾(6A˜ÝAÂ/;AšÝA:A ÝA"6A¤ÝB‹€€€€‚€€€7 A£(6 Aœ)7 A: A·ÝA:A¬ÝA¼ (6A°ÝAÀ -:A±ÝA:AÃÝA:A¸ÝAÞ (6A¼ÝAâ -:A½ÝA:AÄÝA"6AÈÝBŽ€€€€‚€€€7 A³)7 A­)7 A:AìÞAôÝ6AÄÞA€€€6AÀÞAã€6A¤ÞA*6AÈÞAÀÜ(6 AÓÜ,AH@AÐÜ(AÈÜ(r ó‹!~#A0k"$@ E@AÈÜ„!AÈ܃!@ AO@AÈÜ…"A€A‰#Ak"$AÈ܃AÈÜAŠ A: Aj Aj‹ Aj$  AÈÜ A k A AA€† AÈÜAÈÜ(AÓÜ,AN  A:,  AG:/  AG:.  AG:-  AG:+  AG:*  AG:)  AG:(  AG:\'A4"A60 B7( B7 B7 B7 B7 B7 A j" 6 ! a"AøÿÿÿO\r@@ A O@ Ar"Aj!  Aÿÿÿÿk6  6  6   : A j! E\r E\r  ü\n  jA: Aj! A\'j!#AÐk"$@ A j"( , " AH"E@A<"B7 Aà6 B7 B7 B7 B7$ B74 B€€€ü7,  6  A j6  (! AéOA4 Aèn" A4OA jA !A<"\nB7 \nAà6 \nB7 \nB7 \nB7 \nB7$ \nB74 \nB€€€ü7,  \nA j6 (!  \n6@ E\r  ("\nAk6 \n\r  (( | Aj! ("! ( "\n G@@@ \nAk("E\r  ("Ak6 \r  (( |  \nAk"\nG\r (!  6 @A€  A€O"\n ( kAuM\r \nAt"!\n  k"@ \n  ü\n   \nj6  \n j6  \n6 E\r r !@@@@ ("\n ("I@ \n (6 \n ("6 @  (Aj6 \nAj!\n  \n ("k"\nAu"Aj"A€€€€O\rAÿÿÿÿ  k"Au"   K AøÿÿÿO"A€€€€O\r At"" \nj" (6  ("6  j!    (Aj6 ( ( ("k"\nAu  Atk! \n@   \nü\n  6  Aj"\n6  6 E\r r  \n6    Aj!\n@ ,AH@ (A: A6  A: A: \nA€” A:$@ ,3AH@ ((A: A6,  A:3 A:( (" (  , AH6 -! -! -! -! -! -! -!\n -! -! B7( A6$ A6 A6 A6 A6 A6  A tA̞AÀ– r \nAtr Atr Atr Atr Atr Atr Atr6 (  , "AH"! ( ! !\n#A€k" $@ A j"(@A! ("E\rA‹    A4jAAüü 6 6 )7 )7 )7 )7$ ( 6, \n60 AA ("Aq6œ A„j"AA€ü A;ã A:® A;à A:ß A: A;¿ A:ª A:¥ A:„ A€„q@ A:‚ A€€q@ A:â A€ q@ A:¨ A€€€q@ A:Á A€€€q@ A:¯ Aq@ A:Ä Aq@ A:¾ A€q@ A:² A€Âq@ A:€ Aq@A!@ A G A GqE@ jA: Ar"AýqA F@  jA: Aj"A€G\r A E\rA  jAk-"A\rF\r A\nF ! A6` A 6D 64 A€€  A€€OAt6X A„jAÿAÔü B7ä B7Ü@AA \n ("E@ AÌj!% A°jAr!& Aüj!\' AèjAr!( A°j!AÜ!A!@@ !@@ (" K@ B7ø B7ð B7èA! A°jAA  A°jF""j   F"#! (¨!) (!@@ j-"A G A Gq\r A|qAj Aj A F! Aj" G\r ! A°jA,A "j Aj #" 6 A°jA$A "j A j #" 6A! A°jA A "j Aj #"$A6@ (”"AL\r (œ! (! !\n@@  Alj"-A>F@ \n O\r O\r j-A>G\r Aj"!@ Aj" O\r@ j-"\nA G \nA Gq\r A|qAj Aj \nA F! Aj" G\r !   kAkA  G"\n6  6 !  \n ( "I\r  \n k"\n6 ! Aj" G\r ! ! 6ä@@ O\r j-A\nk  N\r (!@  Alj-A>F\r Aj" G\r ! % & " Aj #!A!\nA!A! !@A k!A k! („" (üjAk! (¬E! (! ( !\r (œ!! (¤!@@ ("AG@ !   6@ ! ("M@ !  @ " O\r  ( j-!@  j- AÿqG\r Aj" G\r ! @  k \rI\r@  O\r@@  j-A k Aj" G\r ! 6ä A6 A6¨  6ä  F@   (k"A M6 A6 !  (! @@@@ AG\r AL\r  N\rA! A6¤  O\r  j" -A\nk @ Aj  Aäj.AL\r A6¤ AþÿÿÿqAG\r A6 A6  A6 !  @ AG\r  (”G\r A6  (" (œk"A O6 A6¨  A6@@ AL"\r  G\r ( AljAk-"A>G6¨  A6¨ \r ( AljAk-! AÿqA>F\r  G\r (€@ !  („"A H@ !  (ü jAk-AG@ !  A6¬ !  @ Aq@ !    AL\r  (” G\r   Alj"Ak-A>F\r   G\r  (€\r  A H\r  -AG\r  6A AF\r   A$k(k"A M6 Ak ! A6¬ A6¨@ (" !O\r@ AG\r@ -"A-k !  G\r@@@ Aj" O\r j- F\r @@ j-A k Aj" G\r ! 6ä A6 AA A=F6 !   \nI\r -"" E\rA ÀATE\rA! Aj"\n O\r@@@  \nj-" F"\r A F\r A G\r j! \nAj"\n G\r !\n AI\r  AI\r A\nk @@@  N\r  G\r@ Aj  Aàj Aèj/E\r -è"A>F\r  Alj"-G\r (ð" ( K\r (ô" k j"!@ (à" O\r@ j-"A G A Gq\r A|qAj Aj A F! Aj" G\r 6ä   k6  6 !  6ä   k"6  6 O\r@ j-A\nk  !M@  j"6ô A6  Aj"6ô  Ak6  ! @ !O@ (AF@ !  A6  !k6 A6 !  Aj  Aäj Aèj/! (!@@ @ (ä!@ AG\r  G\r@@ O\r j-"A\rF\r -è! A\nG\r AÿqA>F\r   A>! -èA>F\r   Aÿq"A.G A)Gq\r (ìAF\r   (ô" (ðk j"!@ O\r@ j-"A G A Gq\r A|qAj Aj A F! Aj" G\r ! 6ä   k"6  6  ,è6@@@ O\r j-A\nk Aj6ô   !M@  j6ô A6  Aj6ô  Ak6 E@ Aj  j0\r (”! @ (˜" J@ (!  A Av j AL"6˜ ( Als"E@ (("E\rAå (0   6 (”! AÜ   F! Aj! Aj6”  Alj" )ø7  )ð7  )è7 (”! (! (! ! A F  Fq\r (ä!  ! O@ !  @ j"\n-"A#G@ ! AþF\r AàF\r !  Ak"\nF\rA  Aj"j-A#G\r  \nF\rA  Aj"j-A#G\r  \nF\rA  Aj"j-A#G\r  \nF\rA  Aj"j-A#G\r  \nF\rA  Aj"j-A#G\r  \nF\rA  Aj"j-A#G\r  \nF\r Aj!A  @@  j- G\r Aj" G\r !  k"AI@ !  6 @@@  M\r@  j-A G\r Aj" G\r   M\r@@  j-"A\nk @ AàG\r \n-AàG\r !  Aj" G\r ! 6ä A6 A6 $A6 \n A 6 ! " k "AJ@ !  @  M"\n\r (Aq\r  j-A k"AK@ !  A tA“€€q\r !  @ \n\r@  j-"A G A Gq\r Aj" G\r !  6 6ä A6  6  @@@@@  O\r  j-AF\r Aj" O\r A/G\r  j-A>F\r AjM@A!  A! \rAA  A jAE\rA! ( " O\r \r(!@@  j-"A k" AK\rA tA€€qE\r Aj" G\r  AAA A\nF A\rF! Aj$ "6¤@  (AG\r A6¤ ("A€qE\r (AG\r  (O\r ( j-"A-k Aj  Aäj. F@ A6¤ $A6 A6 AüG\r  (”G\r (€"E\r (AG\r Aäj!\n Aàj!A!A!\r@ Aj"(" M\r (" j-AüG\rA! Aj" O\r@  j-A k" AK\rA tA€€qE\r Aj" G\r ! @@@@  I@  ( j-A:Fj!  O\r (" j-A-G\r@@@  j-"A-G\r Aj" G\r \rAj!\r  A! \rAj!\r@  A:Fj" O\r@@  j-"A k"AK\rA tA€€qE\r  Aj"G\r  AüG\rA!A! Aj" O\r@  j-A k"AK\rA tA€€qE\r Aj" I\r !   O\r@  j-A\nk E\r  ! E\r \n 6  \r6A  A E\r  (à6 A\n6  A6 (”"   F  (AF! A€qE\r  jAL\r ( Alj"Ak-"E\r A?K\rB ­†B€€€€ÀƒP\r@ (ä" ("\n Aj"  \nK"O\r (!@ j-"A G A Gq\r Aj" G\r ! Aj" \nO\r (" j-AÛG\r  Aj"j,"E\rAà ATE\r  j-AÝG\r \n Aj"G@ j-A k"AK\rA tA“€€qE\r Ak ( " -Ar: Ak \'  6@ ("O\r (!@ j-A k"AK\rA tA€€qE\r Aj" G\r ! 6ä  6  Aj"6ô  6  6AÜ!A! ! ! Aj1A! Aj A@k2\r -Aq@ Aj AÜj2\r AjA0\r Aj3\rA!#Ak"\r$ \rA6$ Aj" A6@ (€AJ@ \rAøj!@@@@@@ (ø j"("AÿqAk \r AsA\nvAq6 \r /:  \r (6 \r (AsA\nvAq6 \r /:  \r AÿÿK6 \r /: \r (6  \rA6 \r /At(€a"6 /! \r 6 \r At(€6 \r \rAj6 \r \rA$j6 @@ ("A€q@@ A€qE\r Aÿq \rA j (, ("@ ($"E\rA¯ (,   ("Aÿq"AK\rA tAŽ€qE\r (Ak6 (! A€qE\r Aÿq \rA j (, ("@ ($"E\rAŠ (,   @ ("AÿqAk (Œ (Alj" -Ar: (Aj6  \rB7` \rB7X \rB7P \rB7H \rB7@ \rB78 \rB70 \rB7(@ ("AÿqA\nG\r A€€„I\r ("A€ Av"nM\r Aq! Aj!A!\nA!@ "AO@ A|q!A!@  Atj"( j ( j (j (j ( ( ( (jjjk! Aj! Aj" G\r E\r @  Atj"( j (k! Aj! \nAj"\n G\r  n AvO\r  ($"A¨ (,  (  A€~qA r"6 A! \rA6ˆ \rB7€ \rB7x \rB7p \rB7h ("@ (Œ AljAk-AqE! A!@@@@@@@ AÿqAk \r Av6h  A€€I\r ("\n ("j-! ( !@@@  ("O\r@  \nj- AÿqG\r Aj" G\r  M\r@  \nj-A G\r Aj" G\r ! @  M\r@  \njAk-A G\r Ak" K\r ! A!  \nj  kA \rAèj \rAÈj<\r (! !\n@  M\r@  \nj-A k"AMAA tA€€q\r \nAj"\n G\r !\n  j \n kA  \rA(j<\r \r :ˆ (!A!  \rA6l \r Av6h \r (Ak6p  \r Av6h @@@@@@@  Aÿq"A FqE@  \rAèj (, ("\r (! AÿqAk ($"E\rAŠ (,   (!@ AÿÿM@ E\r Aj!@ ( (F@ A j! Ak"\r  @  A lj"A k( Ak(G\r Ak"\r  Ak"E\r Aj! A  ="E\r  A Aj (="E\r  (!@@ Av"Atq"E@A! ($"E\rAÔ (,  r  @ (! ("! ! !@ !@ M\r (!@  j-A-F\r Aj" G\r ! A!  I@ ( jAk-A:F! @ M\r (!@@  j-"\nA-G\r Aj" G\r !  Ar  \nA:F!  At(°:6 Ak! Aj! AJ\r A A (, ("@ ($"E\rAŠ (,  r  A ( (  >"\rA A (, ("@ ($"E\rA¯ (,  r  AI\r@A A (, ("E@ Aj!A!  ($"E\rAŠ (,  r  @ A  Atj"( (  >"\r Aj" G\r A A (, ("E\r ($"E\rA¯ (,  r  r  Aj (?"\r A!  (Aÿq"A Fq\r  \rAèj (, ("E\r ($"@A¯ (,  ! \r \r(X@ \r(Hr \r(Lr \r(Pr \r(8E\r \r((r \r(,r \r(0r \r (! -AkAM@ A l j!  At j!  (Œ (Alj" -Aþq A\nvAqr: (Aj6 Aj" (€H\r A6€A! \rAj$ "\r -Aq@A!A!#A@j"$@ Aj"(`"E\r (pE\r (X AAW@@AA (, ("E@ (`E\r A0j!\n  ($"E\rAŠ (,   @ (X Alj"( E\r B7 B7 B7 B7 \nB7 \nB7  ( 6(  (6,@  ( (A \n Aj<@A!  A A(j (, ("@ ($"E\rAŠ (,    ( (?"\rA A(j (, ("E@A!  ($"E\rA¯ (,  (@ (r ( r (r \r Aj" (`I\r A!AA (, ("E\r ($"@A¯ (,  ! A@k$ \r A!AA (0 ("E\r (("@A¯ (0  !  \n6ä A6 ! @ (ä"Aj" ("O\r (!@@ j"-A\nk @ -A\nk @ -A\nk @  j-A\nk Aj! Aj!  I\r @ I@ (!@A!@ j-A\nk Aj" G\r ! A! A°jA(A "j Aj #"\n 6 " ("AG\r@@ ("M\r (!@  jAk-"A G A Gq\r Ak" K\r  @  O\r (!@  jAk-A#G\r Ak" K\r   F\r ( jAk-"A F@ !  A F@ !  ! -AqE\r \n 6  !@ AkAI\r  ("M\r (!@  jAk-"A G A Gq\r \n Ak"6  I\r @ ( j-A\rFj! I@ ( j-A\nFj! @ )E\r E\r  j"AL\r ( Alj"Ak-A>F\r (ü Ak(j" (A€r6 @ \r  j" (”N\r Aj 0\r AJ@ AjA Al" (j"(" -Aq ( j,A A4\r AjA (ü" -éAq" ( j,A A4\r ( j" -Aýq r: ( j 6 @ (”!@ -AqE\r ( Alj"Ak-A>G\r (AG\r \n(" ("k"AkA K\r (" j"-AÛG\r -A!G\r  jAk-AÝG\r Ak! Aj!A!@@@@ Ak @  j-"A k  AákAÿqAIAÿq -–"A k  AákAÿqAIAÿqG\r Aj" G\r A  @  j-"A k  AákAÿqAIAÿq -\r"A k  AákAÿqAIAÿqG@ A\nk Aj" G\r A  A!@  j-"A k  AákAÿqAIAÿq -\n"A k  AákAÿqAIAÿqG@ A\nG\r  Aj" G\r A  A!@  j-"A k  AákAÿqAIAÿq -ä"A k  AákAÿqAIAÿqG@ A\nG\r -"A k  AákAÿqAIAÿqAÃG\r -"A k  AákAÿqAIAÿqAÁG\r -"A k  AákAÿqAIAÿqAÕG\r -"A k  AákAÿqAIAÿqAÔG\r -"A k  AákAÿqAIAÿqAÉG\r -"A k  AákAÿqAIAÿqAÏG\r -"A k  AákAÿqAIAÿqAÎG\rA  Aj" G\r A ! Ak" -Ar: ( (”AljAk" -AÇq r: A6 (”!  k!@A!@@A ( Alj"-A)kt"AqE@ A!qE\rA! Aj1  („6 Aj  ( ,A4\r AjA (" -Aq ( j,A A4\r  AjAA -"AqA AvAqA4\r Aj" (”H\r @ (E@ Aj1@A!  A!AÜ! -AÀqE\r ( \n(I\r (ŒAj6Œ  (Œ@@ („"Aj" (ˆ"J@ A€ Av j AL"6ˆ (ü s"E@A! (("E\rAå (0   (€"@   (ükj6€ 6ü („"Aj6„  6„ (ü"\rA!   j"A; (Œ! A6  AtAr6 A6Œ @ $(E\r Aj1E\rA!  @@@@ ("Ak\n A! Aj1\r („"Aj" (ˆ"J@ A€ Av j AL"6ˆ (ü s"E@ (("E\r\nAå (0  \n (€"@   (ükj6€ („"Aj6„ 6ü  j  6„ (ü"E\r  j " (AtAÐÍj(" /Atr6 (! A6   Atr6 6€ Aj 5\r Aj1\rA!AÜ!  (€A: (€ /; (€" (A€r6A! Aj 5\r Aj1\rA! (€E@AÜ!  A6 !  (€A\n: (€ /; A 6AA Aj 5!  @  (F\r Aj1E\rA!  @ (€\r !@ Aj"\n(€"Aj" \n(„"J@ \nA€ Av j AL"6„ \n(ø s"E@A \n($"E\rAå \n(, A  \n(ü"@ \n   \n(økj6ü \n 6ø \n \n(€"Aj6€  j  \n 6€ \n(ø"E\r  j " (AtAÐÍj(" /Atr6 (! A6   Atr6 \n 6üA  A E\rA!  Aj 5! A! E\r  A!  (("E\rAŠ \n  (P"@ (T"A!@@ (P Atj("E\r (@" M@   (D (HljI\r r (T! Aj" I\r (P r (H@A!@ (@ Atj"-"Aq (r -  Aq@ ( r Aj" (HI\r (@r (l"@ (p"A!@@ (l Atj("E\r (\\" M@   (` (dljI\r r (p! Aj" I\r (l r (d@A!@ (\\ Alj(r Aj" (dI\r (\\r (8r (xr (ür (r A€j$ @A<"B7 Aà6 B7 B7 B7 B7$ B74 B€€€ü7,  6  A j6  (@ (("E\r ((" ($"G A$j!A!@@@  At"j("(AF@ ($" (("G\r Aj!   k"Au!@@ ((AF\rA! AG@@ Aj!  Atj"((AF@  O\r Ak(!  Atj(! \r \r !  G\r A! A68 B70A!  A! A68 B70 A6L B7D  A0j6@  AÄj6<@@@@@@  At"j"("(AG\r  Ak(A !  Aj"K@  Atj( rAG\r AF\r -A/F\r Aj" G\r ! F\r Aj  k” I@@ Aj ((  ,3AH j-bÀš Aj" G\r  (," ,3" AH"O\r Av! Aj!\n@ (  Aq!@  j"-S@ Aj" I\r  -A>F\r -A/F\r@@ K@ !@@  j"-A=F\r -S\r -A>F\r -A/F\r Aj" I\r !  G\r Aj!  A6P B7H AÈj  k”  I@@ AÈj ((  ,3AH j-bÀš Aj" I\r @@  (, ,3" AH""O\r (  !@@  j"-SE\r Aj" G\r  -A=G\r@@@@@@ "Aj"M\r  j"-S\r B78 A6@@ -A"F\r -A\'F\r !@  j" -S\r -A>F\r -A/F\r Aj" G\r !  Aj"!@ M\r -!@  j- F\r Aj" I\r ! k"  k" I"AøÿÿÿO\r@@ A O@ Ar" Aj!  Aÿÿÿÿk64  6,  60   :7 A,j! E\r E\r   j ü\n jA: ,CAH@ (@ (8r  (46@  ),78   (, ,3" AHIj!  A6@ B78 ! M\r k"  k" I"AøÿÿÿO\r@@ A O@ Ar" Aj!  Aÿÿÿÿk64  6,  60   :7 A,j! E\r E\r   j ü\n jA: ,CAH@ (@ (8r  (46@  ),78  AÈj6\\ A,j \n AÈj AÜj@ (,"Aj" A8jF\r ,C! ,AN@ AN@ (@6 )87  (8 (<™  (8 A8j AH" (<  ˜ ,CAN\r (@ (8r   A¤AƁ"AüÛ6 AˆÜA  !  AÈj6, A8j \n AÈj A,j (8",AH@ A6 (  A: Aj A: ,SAH@ (P (Hr (,! -3!   Aÿq ÀAH""I\r A!A!@ ( ," AHAG\r ( Aj AH"(Aöґ«s -Aïsr\r A:S A:K A»/;H A½-:J Aj!\nA! AÈj"( , " AH""! (  " !@ "AI\r Ak"Aq@ !  (A•ÓÇÞl"Av sA•ÓÇÞl A•ÓÇÞls! ! Aj ! AI\r !@ (A•ÓÇÞl"Av sA•ÓÇÞl (A•ÓÇÞl"Av sA•ÓÇÞl A•ÓÇÞlsA•ÓÇÞls! Aj! Ak"AK\r @@@@ Ak -At s! -At s!  -sA•ÓÇÞl! @ \n("E\r \n( A\rv sA•ÓÇÞl"Av s" Akq i"AM\r   K\r  p " Atj("E\r ("E\r Ak! AK!\n@@@  ("G@@ \nE@  q!   K\r  p!  G\r  ( ," AH" G\r ( Aj  U\r !  ("\r A  ! ,SAH@ (P (Hr E\r ( ," AHE\rA<"B7 A!6 Aà6 B7 B7 B7 A6( B74 B€€€ü7, A:S AŽ/;H A-:J A:K  AÈj6, A8j Aj AÈj A,j@ (8" F\r Aj! Aj! ,! ,AN@ AN@  (6  )7   ( (™   (  AH" (  ˜ ,SAH@ (P (Hr A j! Aj ,AH@ ( (r @ ,3AH@ ((A: A6,  A:3 A:( @ E\r ( ( "F\r Ak(!  6  6 A$j Aj@ ( "E\r ("Ak6 \r (( | A!  A! E\r  ("Ak6 \r  (( |  A! ( ( F\r  ( " (kA I\r@ Ak("E\r  ("Ak6 \r  (( |  Ak6 Aàj$ à%#A k"$@@ E@A!  @@@@@@@@@@@@@@@@ Ak\n \r  A<"B7 A6 Aà6 B7 B7 B7 A6( B74 B€€€ü7,  6Œ  A j6ˆ  )ˆ7    A<"B7 A6 Aà6 B7 B7 B7 A6( B74 B€€€ü7,@ E\r (! A:• AA  AL" ANA0r:” A”ja"AøÿÿÿO\r@@ A O@ Ar"Aj!  Aÿÿÿÿk6€  6ø  6ü   :ƒ Aøj! E\r E\r  A”j ü\n  jA: AÔÜ6˜ A¤j AjAÔÜ A˜j@ (¤"Aj" AøjF\r ,ƒ! ,AN@ AN@  (€6  )ø7   (ø (ü™   (ø Aøj AH" (ü  ˜ ,ƒAN\r (€ (ør  6ô  A j6ð (Aj6  )ð7  Aj ("Ak6 \r (( |  A<"B7 A 6 Aà6 B7 B7 B7 A6( B74 B€€€ü7,  6ì  A j6è  )è7  Aj \r A<"B7 A 6 Aà6 B7 B7 B7 A6( B74 B€€€ü7, A j!@ E\r ("E\r ("E\r AøÿÿÿO\r@ A O@ Ar"Aj!  Aÿÿÿÿk6€  6ø  6ü   :ƒ Aøj! @   ü\n  jA: (ü -ƒ" ÀAH@ AÄÝ Aøj ,ƒAN\r (€ (ør  6ä  6à (Aj6  )à7  Aj ("Ak6 \r (( | A<"B7 A\r6 Aà6 B7 B7 B7 A6( B74 B€€€ü7,  6Ü  A j6Ø  )Ø7  A j A<"B7 A6 Aà6 B7 B7 B7 A6( B74 B€€€ü7, A j!@ E\r ("AF\r Aøj œ A¬Ý Aøj ,ƒAN\r (€ (ør  6Ô  6Ð (Aj6  )Ð7(  A(j ("Ak6 \r\n (( | \n A<"B7 A6 Aà6 B7 B7 B7 A6( B74 B€€€ü7, A j!@ E\r (E\r A”Ý AøjAû" , AH@ ( (r A Ý AøjAûA› -AßqAØF" , AN\r ( (r  6Ì  6È (Aj6  )È70  A0j ("Ak6 \r (( | A<"B7 A6 Aà6 B7 B7 B7 A6( B74 B€€€ü7, A j!@ E\r@ - "E\r A:¥  :¤ AøÜ Aøj A¤j" , AN\r ( (r ("E\r ("E\r AøÿÿÿO\r\n@ A O@ Ar"Aj!  Aÿÿÿÿk6€  6ø  6ü   :ƒ Aøj! @   ü\n  jA: (ü -ƒ" ÀAH@ AˆÝ Aøj ,ƒAN\r (€ (ør  6Ä  6À (Aj6  )À78  A8j ("Ak6 \r (( |  A<"B7 A6 Aà6 B7 B7 B7 A6( B74 B€€€ü7,  6¼  A j6¸  )¸7@  A@k  A<"B7 A6 Aà6 B7 B7 B7 A6( B74 B€€€ü7, A j!@ E\r Aøj (œ A¸Ý6˜ A¤j AjA¸Ý A˜j@ (¤"Aj" AøjF\r ,ƒ! ,AN@ AN@  (€6  )ø7   (ø (ü™   (ø Aøj AH" (ü  ˜ ,ƒAN\r (€ (ør  6´  6° (Aj6  )°7H  AÈj ("Ak6 \r (( |  A<"B7 A6 Aà6 B7 B7 B7 A6( B74 B€€€ü7, A j!@ E\r A:€ BãÞ±›ô­·ô7ø A:ƒ A¤j (œ  Aøj6” A˜j Aj" Aøj A”j@ (˜"Aj" A¤jF\r ,¯! ,AN@ AN@  (¬6  )¤7   (¤ (¨™   (¤ A¤j AH" (¨  ˜ ,¯AH@ (¬ (¤r ,ƒAH@ (€ (ør A"6ø BŒ€€€€‚€€€7ü Aù (6 Añ )7 A: A¤j (œ  Aøj6” A˜j  Aøj A”j@ (˜"Aj" A¤jF\r ,¯! ,AN@ AN@  (¬6  )¤7   (¤ (¨™   (¤ A¤j AH" (¨  ˜ ,¯AH@ (¬ (¤r ,ƒAH@ (€ (ør A"6ø BŒ€€€€‚€€€7ü Aì (6 Aä )7 A: A¤j (œ  Aøj6” A˜j  Aøj A”j@ (˜"Aj" A¤jF\r ,¯! ,AN@ AN@  (¬6  )¤7   (¤ (¨™   (¤ A¤j AH" (¨  ˜ ,¯AH@ (¬ (¤r ,ƒAN\r (€ (ør  6   6œ (Aj6  )œ7P  AÐj ("Ak6 \r (( |  A<"B7 A6 Aà6 B7 B7 B7 A6( B74 B€€€ü7,  6˜  A j6”  )”7X  AØj  A<"B7 A6 Aà6 B7 B7 B7 A6( B74 B€€€ü7,  6  A j6Œ  )Œ7`  Aàj  A<"B7 A6 Aà6 B7 B7 B7 A6( B74 B€€€ü7,  6ˆ  A j6„  )„7h  Aèj  A<"B7 Aà6 B7 B7 B7 A6( B74 B€€€ü7, AA AF6 @ E\rAš\n! (Ak"AM@ At(Ð! A:ƒ A:ý Aá\r(6ø Aå\r-:ü a"AøÿÿÿO\r@@ A O@ Ar"Aj!  Aÿÿÿÿk6¬  6¤  6¨   :¯ A¤j! E\r E\r   ü\n jA:  Aøj6” A˜j Aj Aøj A”j@ (˜"Aj" A¤jF\r ,¯! ,AN@ AN@ (¬6 )¤7  (¤ (¨™  (¤ A¤j AH" (¨  ˜ ,¯AH@ (¬ (¤r ,ƒAN\r (€ (ør  6€  A j6|  (Aj6  )|7p  Aðj  ("Ak6 \r  (( |  A:$ ,3AH@ ((A: A6,  A:3 A:( A j$    #Ak"$@ ( ," AHE\r ( " (F\rA<"B74 B€€€ü7, A6 Aà6 B7 B7 B7$  Aj")7  (6 A: A: Ak(!  6  A j6 A$j Aj@ ( "E\r  ("Ak6 \r  (( | ,AH@ (A: A6  A: A: Aj$ ª~A!@@@ (Ak ( ," AH""E\r  ( Aj "j! !@@ 1"B?V\rB †B€Ì€€ƒP\r Aj" G\r  kAF A!  ¹  #Ak"$ ("(" ("kAu!@  F\r@  Atj(E\r Aj" G\r ! @@ " M\r  Ak"Atj(\r A<"B7 A6 Aà6 B7 B7 B7 A6( B74 B€€€ü7,  6  A j6 A0j!  At"j!  At"j!@  kAu" (" ("kAuM@ (" k"Au I@  j!  G@@ (! ("@  (Aj6  6 (!  6@ E\r  ("Ak6 \r  (( | Aj! Aj" G\r (! !  G@@  (6  ("6 @  (Aj6 Aj! Aj" G\r    kj6   G@@ (! ("@  (Aj6  6 (!  6@ E\r  ("Ak6 \r  (( | Aj! Aj" G\r (!  G@@@ Ak("E\r  ("Ak6 \r  (( |  Ak"G\r  6  @ ! (" G@@@ Ak("E\r  ("Ak6 \r  (( |  Ak"G\r ( (!  6 r A6 B7A! @ A€€€€O\rAÿÿÿÿ Au"  K AøÿÿÿO"A€€€€O\r  At""6  6   j6  G@@  (6  ("6 @  (Aj6 Aj! Aj" G\r  6   ( Aj@ ( "E\r  ("Ak6 \r  (( | ("(! (!  G@@@ Ak("E\r  ("Ak6 \r  (( |  Ak"G\r  6 Aj$ A„  )A¤€"A€Ú6 A”Ú6 AèÚA  ~ AL@ (" ("kAu N@  k"Au"\n H@@   j" F@ !  ! !@  (6  ("6 @  (Aj6 Aj! Aj" G\r 6 \nAL@  At"j! !   k"K@ !@  (6  (6 B7 Aj! Aj" I\r 6  G@@ Ak")! B7 Ak(! Ak" 7@ E\r  ("Ak6 \r  (( |  G\r  F@ !@ (! ("@  (Aj6  6 (!  6@ E\r  ("Ak6 \r  (( | Aj! Aj" G\r   At"j! !   k"K@ !@  (6  (6 B7 Aj! Aj" I\r 6  G@@ Ak")! B7 Ak(! Ak" 7@ E\r  ("Ak6 \r  (( |  G\r  Atj! !@ (! ("@  (Aj6  6 (!  6@ E\r  ("Ak6 \r  (( | Aj! Aj" G\r  @  ("kAu j"A€€€€I@Aÿÿÿÿ  k"Au"   I AøÿÿÿO" A€€€€O\r AtA "  kj! At"Ak"Aq   (6  ("6 @  (Aj6 Aj! Aj !  j! @@  (6  ("6 @  (Aj6  (6  ( "6 @  (Aj6 Aj! Aj" G\r ( k"@   ü\n 6   ("k"k! @   ü\n  j6 6 ( Atj6 @ r    Ý#A k"$ ($" (("G@@ ( Aj" G\r @ (AG\r ($" (("F\r !@@@@@ (("  k"AH\r  "6  6   j6 A6 B7  Aj6  Aj6@ Aj!@@ (("  Aj!    Aj"G\r  Aj" G\r    ($"@ " (("G@@@ Ak("E\r  ("Ak6 \r  (( |  Ak"G\r ($! 6( (, r (6$ (6( (6, A6 B7 ("E\r " ( "G@@@ Ak("E\r  ("Ak6 \r  (( |  Ak"G\r (!  6 ( r ("E\r " ("G@@@ Ak("E\r  ("Ak6 \r  (( |  Ak"G\r (!  6 ( r A j$ ¶ ~#A k"$@@@ ($" (("F\r@ ("("A G A GqE@  Aj" G\r ((" ($"F\r A$j! @  \nAt"\rj("(" A\rkAO \nAjA!@ ($" (("F\r !@@@ ("(AG\r (( ($"kAG\r ((A!F\r Aj" G\r  A6 B7 A6 B7@@@ ("(AG\r (( ($"kAG\r ((A!G\r (" ( "G@A<"B7  6 Aà6 B7 B7 B7 B€€€€€€€À?7(  6  A j6  (68  64  60 A6 B7 Aj @ ("E\r  ("Ak6 \r  (( | (($! (" ("I@  (6  ("6 @  (Aj6  Aj6   ("k"Au"Aj"A€€€€O\rAÿÿÿÿ  k"Au"   I AøÿÿÿO"A€€€€O\r At"" j" (6  ("6  j!    (Aj6 ( ( k"Au  Atk! @   ü\n  6  Aj"6  6 @ r  6  Aj  Aj" G\r @ (" ( "F\rA<"B7  6 Aà6 B7 B7 B7 B€€€€€€€À?7(  6  A j6  (68  64  60 A6 B7 Aj  ("E\r  ("Ak6 \r  (( | ($ \rj" ! Aj" (("G@@ )! B7 (!  7@ E\r  ("Ak6 \r  (( | Aj! Aj" G\r ((!  G@@@ Ak("E\r  ("Ak6 \r  (( |  Ak"G\r 6( (" ("  kAu (" ! ( k! ("@ " ( "G@@@ Ak("E\r  ("Ak6 \r  (( |  Ak"G\r (!  6 ( r (! @ " ("G@@@ Ak("E\r  ("Ak6 \r  (( |  Ak"G\r (!  6 ( r Au! ($! ((!  \nj !\n \n  kAuI\r A j$   Þ#Ak"$ @ ("E\r ( " (F\r Ak(! ("@  (Aj6 Aj!  6  6 A$j Aj@ ( "E\r ("Ak6 \r (( |   @ ("E\r  ("Ak6 \r  (( | Aj$ ¢  } ( , " AH""! (  " !@ "AI\r Ak"Aq@ !  (A•ÓÇÞl"Av sA•ÓÇÞl A•ÓÇÞls! ! Aj ! AI\r !@ (A•ÓÇÞl"Av sA•ÓÇÞl (A•ÓÇÞl"Av sA•ÓÇÞl A•ÓÇÞlsA•ÓÇÞls! Aj! Ak"AK\r @@@@ Ak -At s! -At s!  -sA•ÓÇÞl! A\rv sA•ÓÇÞl"Av s! @ ("E\r (  Akq i"AM\r   K\r  p "Atj("E\r ("E\r Ak!\n AK! @@  ("G@@ E@  \nq!   K\r  p!  F\r  ( ," AH G\rA ( Aj AH UE\r ("\r A " 6 A6 Aj!@ (", AN@  (6  )7  (! (!\n#Ak" $@@@ \n‘@ " \n’  \nA÷ÿÿÿK\r Aj \nŒAj“ (   ("6  (   \n6   \nAj‰ Aj$   A6 B7 *!\r ( Aj³!@ @ \r ³” ]E\r @A  AkqAG AIr Atr"  \r•ü"  K"AF\r   AkqE\r w " ("M@  M\r ( ³ *•ü! @ AI\r iAK\r AA Akgkt AI  w "  K" O\r !@@ "@ A€€€€O\r At"! (!  6 @ ( r (!  6 @ A ü ("E\r Aj! (!@ i" AM@  Akq!   I\r  p! Atj 6 ("E\r Ak!\n AK! @ (!@ E@  \nq!   I\r  p! @  F@ !  Atj" (E@ 6 ! !   (6  ((6 ( 6 ("\r  (! A6 @ ( r A6   (" Ak"qE@  q!   K@ !   p! @ (" Atj"("E@  (6  6  Aj6 ("E\r (!@  Ak"qE@  q!   K\r  p!  Atj 6   (6  6  ( Aj6 A : 6 ¡#Ak"$  6 Aj Aj  Aj@ ("Aj" F\r , ! ,AN@ AN@  (6  )7   ( (™   (  AH" (  ˜ Aj$ } a"AøÿÿÿI@@@ A O@ Ar"Aj! Aÿÿÿÿk6 6 6  : ! E\r E\r   ü\n  jA:   o ("@@ (! ,AH@ ( (r ,AH@ ( (r r "\r (! A6 @ ( r  (" ("I@  (6  (6 B7 Aj6 @  ("k"Au"Aj"A€€€€I@Aÿÿÿÿ  k"Au"   I AøÿÿÿO" A€€€€O\r AtA " j" (6  (6 B7  Atk! @   ü\n  Atj6 Aj"6 6 @ r 6   Î#Ak"$ @ ("E\r ( ( "F\r Ak(! ("@ (Aj6  6  6 A$j Aj ( "E\r ("Ak6 \r (( | @ ("E\r  ("Ak6 \r  (( | Aj$ Ý#A0k"$ ("(" ("G@ !@@@ (@  Aj"G\r  A<"B7 A6 Aà6 B7 B7 B7 A6( B74 B€€€ü7,  6  A j6 A: A¢\n(6 A¦\n-: A: A: AôäÕ«6 A:  A j6$ A(j Aj A j A$j@ (("Aj" F\r ,AN@  (6  )7   A˜ , AN\r ( (r ,AH@ ( ( r (! (0"@ " (4"G@@@ Ak("E\r  ("Ak6 \r  (( |  Ak"G\r (0!  64 (8 r A68 B70  (60  (64  (68 A6 B7 ( Aj ("E\r  ("Ak6 \r  (( |  @ (  Aj" G\r ("(" ("G@@@ Ak("E\r  ("Ak6 \r  (( | Ak"G\r  6 A0j$ AßÜ,AH@AÜÜ(AÔÜ(r AëÜ,AH@AèÜ(AàÜ(r A÷Ü,AH@AôÜ(AìÜ(r AƒÝ,AH@A€Ý(AøÜ(r A“Ý,AH@AÝ(AˆÝ(r AŸÝ,AH@AœÝ(A”Ý(r A«Ý,AH@A¨Ý(A Ý(r A·Ý,AH@A´Ý(A¬Ý(r AÃÝ,AH@AÀÝ(A¸Ý(r AÏÝ,AH@AÌÝ(AÄÝ(r Aà6  Aà6 r ¬#Ak"$ A j"($"@ " (("G@@@ Ak("E\r ("Ak6 \r (( |  Ak"G\r ($!  6( (, r Aj ,AH@ (  (r Aj$  r µ  (!@@@@@@@@@@@@ ( Ak  Aj"M@  6A Ak! (!@@ ! !@ j"-"AF\r @ Aj" O\r -"A k  AákAÿqAIAÿqAÓG\r -"A k  AákAÿqAIAÿqAÃG\r -"A k  AákAÿqAIAÿqAÒG\r -"A k  AákAÿqAIAÿqAÉG\r -"A k  AákAÿqAIAÿqAÐG\r -"A k  AákAÿqAIAÿqAÔG\r  j-A>F\r @ Aj" O\r -"A k  AákAÿqAIAÿqAÓG\r -"A k  AákAÿqAIAÿqAÔG\r -"A k  AákAÿqAIAÿqAÙG\r -"A k  AákAÿqAIAÿqAÌG\r -"A k  AákAÿqAIAÿqAÅG\r  j-A>F\r A\nj" O\r -"A k AákAÿqAIAÿqAÔG\r -"A k AákAÿqAIAÿqAÅG\r -"A k AákAÿqAIAÿqAØG\r -"A k AákAÿqAIAÿqAÔG\r -"A k AákAÿqAIAÿqAÁG\r -"A k AákAÿqAIAÿqAÒG\r -"A k AákAÿqAIAÿqAÅG\r - "A k AákAÿqAIAÿqAÁG\r  j-A>F\r\r Aj" G\r !  6A Aj" O\r Ak! (!@@  j"-A\nk\n\n /A­Ús -A>srE\r Aj! Aj!  I\r !  Aj" O\r Ak! (!@@  j"-A\nk /A¿üF\r Aj! Aj!  I\r !  Aj" O\r Ak! (!@@@  j-"A\nk  A>F\r Aj! Aj!  I\r !  Aj" O\r Ak! (!@@  j"-A\nk /Aݺs -A>srE\r Aj! Aj!  I\r !  @@  O\rA! ( j-A\nk  6 ( !   6A  6A  6A  6A  6A  Aj6A Å@  ("O\r  (˜O\r @ (" j-"E\r A>F@ A>:  6  -Aüq: Aj! Aj  A?K\rB ­†B€€€€€ ƒP\r  Aj"K@  j-A k"AK\rA tA“€€qE\r  :  6  -Aüq: Aj  A! A6  A j"  I"\nO\rA! !@@ j-" A0kAÿqA K\r  A\nljA0k"6 Aj" \nG\r \n! M\r O\r@ j-" A)k  Aj"K@  j-A k"AK\rA tA“€€qE\r  :  6  -Aüq:  k jAj 6  6A!  ç  ("H@@A!@@@A (Œ Alj"Ak"-A)kt"AqE@ A!qE\rA! Ak(!A! Ak-Aq@ ( j,! A! A  A4\r A ,A4\r  AA Ak-"AqA AvAqA4E\rA!  (Ak"6  H\r A Þ#A0k"$@ (ü"E\r@@@ ("AÿqAk A€qE\r (" (O\r ( j-AÛG\r@ ("E\r Aj! AG\r !  @ \r@ A/G\r Aj" O\r \n j-A>F\r AL\r@ AßqAÁkAÿqAI\r AßF\r A:G\r  Aj"M@A!  @@@ \nj,"A0kAÿqA\nI\r A_qAÁkAÿqAI\r E@A!  A ATE\r A!  Aj"G\r  A!  A! @@ Ak A=G\r Aj!A!  A+!@@@@ A"k E\r AÑ AT\r A\rF\r A)!  A*! Aj! I\r A! E\r \rF\rA  A)FA !  Aj" Atj"(! (" I\r   M@A A!  Aj6 „#Ak"$@  O\r@@@ j"  k A j7"AÿK@A!A!@@@  jAm"AtA°j("\nAu j"AtA°j(Aÿÿÿq K@ Ak!   \nAvAq j"AtA°j(AÿÿÿqM\r Aj!  L\r  AH\r  A F\r A F\r A kAI\r -A\nk ( j" I\r Aj$  à@@@ AÿK@A­!@@@  jAm"AtAÐj("Au j"AtAÐj("Aÿÿÿq K@ Ak!  AvAq j"AtAÐj(AÿÿÿqM\r Aj!  N\r  AH\rAà9!  A6  A r AÁkAI6 A!A4!@@@  jAm"AtAÐ2j("Au j"AtAÐ2j("Aÿÿÿq M@ AvAq j"AtAÐ2j(Aÿÿÿq O@ AH\rAð9!  Aj!  Ak!  N\r A!A!@@@  jAm"AtAà7j("Au j"AtAà7j("Aÿÿÿq M@ AvAq j"AtAà7j(Aÿÿÿq O@ AH\rA€:!  Aj!  Ak!  N\r A6  6  ( ( " lAtj! At"@   ü\n  6 F\r ( Aÿÿÿq"AjF@  sAsAq j6  ( kj6 õ #A k"$ B7 B7 B7 B7 A B! A B! @@@  K@   M\r @ \nE@   AjF!A! AqE@   F! A!  Atj( Aj Atj(k"\r Aj" ( " I! Aj" (" I!\n  K\r  I\r  K\r  I\r A! A j$  iA!@ ("(" ("("I\rA!  K\r ( ( ( (D"\rA! (" ("I\r K!  ‰#Ak"$@@@  O\r j  k A j7! ( j! AÿK@A!@@@  jAm"AtA°j("\nAu j" AtA°j(Aÿÿÿq K@ Ak!   \nAvAq j"AtA°j(AÿÿÿqM\r Aj!  L\r  AN\r  A F\r A F\r A kAO\r A6 A 6  B!   C Aj$  D ("(" ("("I@A  K@A ( ( ( (D ž“#A0k"$ A6x#Ak"$ AjAA€ü @@@ E\r Ak! A€j!\r  AtjAk!@  Atj"(!@ !@ !@ Aj" ("O@ !  (! @ \r  j"-j-@ !  \r -j-@ !  \r -j-@ !  \r  j-j-@ !  Aj! Aj"!  K\r @  K@ (!@ \r  j"-" j-\r Aj" G\r Aj" I\r  @AA@@@@@@ AÜF@A! Aj" (O\r@  j-"A!kAÿqAI\r@ AÿqA\nku Aj I\r Aj! @@ (x" (|"N@ AÀ Av j AL"6| (t Als"\rA! ($"\rE\rAå (, \r  Aj6x (t"\r  6t (x"Aj6x  Alj"AÜ ; B7  Aj"6  6 A!@@@@@@@@@@@@ A!k\\ \r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\n\r \r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r Aj"!\n@  M\r@  \nj- G\r \nAj"\n I\r !\n A!A!A!  (F\r Q"AÿM\rA! A!@@@@  jAm" AtA°j("Au j"AtA°j(Aÿÿÿq K@ Ak!   AvAq j" AtA°j(AÿÿÿqM\r Aj!  N\r  A! AN\r A! Aä!@@@  jAm" AtAÀ:j("Au j"AtAÀ:j(Aÿÿÿq K@ Ak!   AvAq j" AtAÀ:j(AÿÿÿqM\r Aj!  N\r A! AN   k! !@@  j-" AàG\r Aj" G\r !A  A F ! !  k"A K\r At j( "  AtjAk(O\rA!A!@ E@ ! !\n  !\n  " I\r @@@@ \nO\r@  j-"A G@ AàF\rA! Aj" \nG\r A! \n  ! \nO@A! !  @  j-AàG" @ ! !  Aj" \nG\r ! \n! @  k"F@A!\n  Atj" (" I@  jAk-A F!\n As  Gq\r \r F \nrE\r E\r Aj  @ F\rA! AK\r At jA j" (" K6 \r  Aj"M@A!   Atj"\n(! \n(!\n  ( ! \n@ Ak!  Ak(" ("O\r@  j-"A G A Gq\r Aj" G\r ! @@ (x" (|"N@ AÀ Av j AL"6| (t Als"\rA! ($"\rE\rAå (, \r  Aj6x (t"\r  6t (x"Aj6x  Alj"Aà; B7  6  6@@ (x" (|"N@ AÀ Av j AL"6| (t Als"\rA! ($"\rE\rAå (, \r  Aj6x (t"\r  6t (x"Aj6x  Alj"Aà; B7  6  6 (t (x"Alj"Ak" Ak6 A(k" Ak6  -Ar:  -Ar:A! ! ! ! (M\r@@@@   jAv"Atj"( K@ E\r  AtjAk( I\r Ak!  (K\r ! ! !  Aj! A!  M\r ! !  @@ (x" (|"N@ AÀ Av j AL"6| (t Als"\rA! ($"\rE\rAå (, \r  Aj6x (t"\r  6t (x"Aj6x  Alj"A¦; B7  Aj"6  6  (x"AL\r (t" AljAk-A&G\r (|" L@ AÀ Av j AL"6|  Als"E@A! ($"\rE\rAå (, \r  6t (x! Aj6x  Alj"A»; B7  Aj6  6  ("\n - AÀq\r\n   k"  \n A jA\r (" AjM\r -A!G\r  Aj"j-A-G\r -A-G\r A! (è" K  \nAkOq\r @ Aj" \n \nI"M@  j" /A­Ús -A>srE\r\r@@ Aj! Aj" K\r " j" /A­Ús -A>sr\r  !  \nI Aj" Kq@  Atj"(! (!  6è (! A! -AqE\r Aj" O\r  j-AüG\r@@ (x" (|"N@ AÀ Av j AL"6| (t Als"\rA! ($"\rE\rAå (, \r  Aj6x (t"E\r  6t (x"Aj6x  Alj"Aü; B7  Aj"6  6  ("Aj K\r  Ak"j"/A÷îs -A÷sr\r @  F\r Q"AÿK@A!A!@@@@  jAm" AtA°j("\nAu j"AtA°j(Aÿÿÿq K@ Ak!   \nAvAq j"AtA°j(AÿÿÿqM\r Aj!  N\r  AN\r A!Aä!@@@  jAm" AtAÀ:j("\nAu j"AtAÀ:j(Aÿÿÿq K@ Ak!   \nAvAq j"AtAÀ:j(AÿÿÿqM\r Aj!  N\r  AH\r\r  A F\r A F\r A\rkA}K\r A!kAI\r A:kAI\r AÛkAI\r AÿG AúKqE\r @@ (x" (|"N@ AÀ Av j AL"6| (t Als"\rA! ($"\rE\rAå (, \r  Aj6x (t"E\r  6t (x"Aj6x  Alj"A®; B7  Aj"6  6@@ (x" (|"N@ AÀ Av j AL"6| (t Als"\rA! ($"\rE\rAå (, \r  Aj6x (t"E\r  6t (x"Aj6x  Alj" (6 (! AÄ; B7  6  Aj!@@ (" Aj K\r  Ak"\nj(AèèуG\r  M\r /A¯ÞF\r @ Aj K\r  Ak"\nj"(Aèèуs -Aósr\r  M\r /A¯ÞF\r Aj K\r  Ak"\nj"/Aæès -Aðsr\r  M\r /A¯ÞG\r @@ (x" (|"N@ AÀ Av j AL"6| (t Als"\rA! ($"\rE\rAå (, \r  Aj6x (t"E\r  6t (x"Aj6x  Alj"Aº; B7  6  \n6@@ (x" (|"N@ AÀ Av j AL"6| (t Als"\rA! ($"\rE\rAå (, \r  Aj6x (t"E\r  6t (x"Aj6x  Alj" (6 (! AÄ; B7  6 Aj!  (Aj K\r @ Ak-"AßqAÁkAÿqAO@ Aj O\r A0kAÿqA\nO\r  Aj O\r\n  Aj"j-"A0kAÿqA\nO@ A_qAÁkAÿqAK\r\n @@ (x" (|"N@ AÀ Av j AL"6| (t Als"\rA! ($"\rE\rAå (, \r  Aj6x (t"E\r  6t (x"Aj6x  Alj"AÀ; B7  6  6@@ (x" (|"N@ AÀ Av j AL"6| (t Als"\rA! ($"\rE\rAå (, \r  Aj6x (t"E\r  6t (x"Aj6x  Alj" (6 (! AÄ; B7  6 Aj!  @@ (x" (|"N@ AÀ Av j AL"6| (t Als"\rA! ($"\rE\rAå (, \r  Aj6x (t"E\r  6t (x"Aj6x  Alj"AÝ; B7  Aj"6  6 \r @@ (x" (|"N@ AÀ Av j AL"6| (t Als"\rA! ($"\rE\rAå (, \r  Aj6x (t"E\r  6t (x"Aj6x  Alj" 6A!A  Aj" O\r  j-AÛG\r@@ (x" (|"N@ AÀ Av j AL"6| (t Als"\rA! ($"\rE\rAå (, \r  Aj6x (t"E\r  6t (x"Aj6x  Alj" 6A!!A !  :  : B7   j"6@@ (x" (|"N@ AÀ Av j AL"6| (t Als"\rA! ($"\rE\rAå (, \r  Aj6x (t"E\r  6t (x"Aj6x  Alj"AÄ; B7  6  6@@ (x" (|"N@ AÀ Av j AL"6| (t Als"\rA! ($"\rE\rAå (, \r  Aj6x (t"E\r  6t (x"Aj6x  Alj"AÄ; B7  6  6 \n @@ E@  -\rA qAvq\r  E\r @@ (x" (|"N@ AÀ Av j AL"6| (t Als"\rA! ($"\rE\rAå (, \r  Aj6x (t"E\r  6t (x"Aj6x  Alj"A:  : B7  Aj"6  6 \n !@@@@@@@@@AA@@AA@@@@@@@@@@ > AþF\r AÞG\r -AqE\r Aj" !@  M\r@@  j-AÞG\r Aj" I\r ! !  kAG\r A! A!  j ( kA7"AÿM@ A F\r A F\r A kAM\rA  @@@  jAm"AtA°j("Au j"\nAtA°j(Aÿÿÿq K@ \nAk!   AvAq j"AtA°j(AÿÿÿqM\r Aj!  N\r A  \nAN\rA  A !  (F\r Q"AÿM\rA!A!@@@  jAm" AtA°j("Au j"\nAtA°j(Aÿÿÿq K@ \nAk!   AvAq j"AtA°j(AÿÿÿqM\r Aj!  N\r !  \nAN\r !  -A qE\r@ Aj" O\r  j" -A=F\r !  kAG\rA!A!AA ( kA7"AÿM@A! A F\r A F\r A kAI  @@@  jAm" AtA°j("Au j"\nAtA°j(Aÿÿÿq K@ \nAk!   AvAq j"AtA°j(AÿÿÿqM\r Aj!  N\r A!\n \nAN !  -A€qE\r@ Aj" O\r  j" -A+F\r !  kAG\rA!A!AA ( kA7"AÿM@A! A F\r A F\r A kAI  @@@  jAm" AtA°j("Au j"\nAtA°j(Aÿÿÿq K@ \nAk!   AvAq j"AtA°j(AÿÿÿqM\r Aj!  N\r A!\n \nAN !  A! Aj"\n!@  \nM"\r@  j-AþG" \r Aj" I\r ! @  k"AF@ ( "A€€qE\r@ \rA! A!  \nj ( \nkA7"AÿM@ A F\r A F\r A kAM\rA  @@@  jAm"AtA°j(" Au j"AtA°j(Aÿÿÿq K@ Ak!   AvAq j"AtA°j(AÿÿÿqM\r Aj!  N\r A  AN\rA  A !  (F\r Q"AÿM\r\rA!A!@@@  jAm" AtA°j(" Au j"AtA°j(Aÿÿÿq K@ Ak!   AvAq j"AtA°j(AÿÿÿqM\r Aj!  N\r !  AN\r !  ! AK\r ( ! ! A€qE\rA!  (M\r\n Q"AÿM\rA!\nA!@@@@  \njAm"AtA°j(" Au j" AtA°j(Aÿÿÿq K@ Ak!   AvAq j"\nAtA°j(AÿÿÿqM\r \nAj!\n  \nN\r  AN\r A!\nAä!@@@  \njAm"AtAÀ:j(" Au j" AtAÀ:j(Aÿÿÿq K@ Ak!   AvAq j"\nAtAÀ:j(AÿÿÿqM\r \nAj!\n  \nN\r A! AN @ Aj" O" E@  j-A$F\r !  kAK\rA!  (M\r Q"AÿM\rA!\nA!@@@@  \njAm"AtA°j(" Au j" AtA°j(Aÿÿÿq K@ Ak!   AvAq j"\nAtA°j(AÿÿÿqM\r \nAj!\n  \nN\r  AN\r A!\nAä!@@@  \njAm"AtAÀ:j(" Au j" AtAÀ:j(Aÿÿÿq K@ Ak!   AvAq j"\nAtAÀ:j(AÿÿÿqM\r \nAj!\n  \nN\r A! AN  @ Aj" O\r@  j-A k"AK\rA tA€€qE\r Aj" I\r ! A F@ !  kAI\r @@ (x" (|"N@ AÀ Av j AL"6| (t Als"\rA! ($"\rE\r!Aå (, \r ! Aj6x (t"E\r  6t (x"Aj6x  Alj"A:  : B7  6  6  @@ (x" (|"N@ AÀ Av j AL"6| (t Als"\rA! ($"\rE\r Aå (, \r Aj6x (t"E\r  6t (x"Aj6x  Alj"A€ ; B7  Aj"6  6  A! !  kAG\r A! !  kAG\r A F\r A F\r A\rkA}K\r AÿG AúKq A!kAI A:kAIr AÛkAIrr ! @ \rA! A!@  j" ( k" A7"AÿM@ A F\r A F\r A kAO\r  @@@  jAm"AtA°j("Au j"\nAtA°j(Aÿÿÿq K@ \nAk!   AvAq j"AtA°j(AÿÿÿqM\r Aj!  N\r  \nAN\r A!Aä! A7"AÿM@ AÿG AúKq A!kAI A:kAIr AÛkAIrr  @@@  jAm" AtAÀ:j("Au j"\nAtAÀ:j(Aÿÿÿq K@ \nAk!   AvAq j"AtAÀ:j(AÿÿÿqM\r Aj!  N\r A!\n \nAN ! !  Aq "E\r @@ (x" (|"N@ AÀ Av j AL"6| (t Als"\rA! ($"\rE\rAå (, \r  Aj6x (t"E\r  6t (x"Aj6x  Alj" : A$: B7  6  6  A F\r A F\r A\rkA}K\r AÿG AúKq A!kAI A:kAIr AÛkAIrr ! @ E\rA! A!@  j" ( k" A7"AÿM@ A F\r A F\r A kAO\r  @@@  jAm"AtA°j("Au j"\nAtA°j(Aÿÿÿq K@ \nAk!   AvAq j"AtA°j(AÿÿÿqM\r Aj!  N\r  \nAN\r A!Aä! A7"AÿM@ AÿG AúKq A!kAI A:kAIr AÛkAIrr  @@@  jAm" AtAÀ:j("Au j"\nAtAÀ:j(Aÿÿÿq K@ \nAk!   AvAq j"AtAÀ:j(AÿÿÿqM\r Aj!  N\r A!\n \nAN ! !  Aq "E\r @@ (x" (|"N@ AÀ Av j AL"6| (t Als"\rA! ($"\rE\rAå (, \r  Aj6x (t"E\r  6t (x"Aj6x  Alj" : Aþ: B7  6  6  A F\r A F\r A kAM\r !  A! ! AqE\r @@ (x" (|" N@ AÀ Av j AL"6| (t Als" \rA! ($"\rE\rAå (, \r  Aj6x (t" E\r  6t (x"Aj6x Alj" : Aþ: B7  \n6  6  @@  (F\r Q"AÿK@A!A!@@@  jAm" AtA°j("Au j"\nAtA°j(Aÿÿÿq K@ \nAk!   AvAq j"AtA°j(AÿÿÿqM\r Aj!  N\r !  \nAN\r !  A F\r A F\r A kAM\r !  A! ! AqE\r\r @@ (x" (|" N@ AÀ Av j AL"6| (t Als" \rA! ($"\rE\rAå (, \r  Aj6x (t" E\r  6t (x"Aj6x Alj" : A+: B7  6  6 \r @@  (F\r Q"AÿK@A!A!@@@  jAm" AtA°j("Au j"\nAtA°j(Aÿÿÿq K@ \nAk!   AvAq j"AtA°j(AÿÿÿqM\r Aj!  N\r !  \nAN\r !  A F\r A F\r A kAM\r !  A! ! AqE\r @@ (x" (|" N@ AÀ Av j AL"6| (t Als" \rA! ($"\rE\rAå (, \r  Aj6x (t" E\r  6t (x"Aj6x Alj" : A=: B7  6  6 A F\r A F\r A kAM\r !  A! ! AqE\r @@ (x" (|" N@ AÀ Av j AL"6| (t Als" \rA! ($"\rE\rAå (, \r  Aj6x (t" E\r  6t (x"Aj6x Alj" : AÞ: B7  6  6 @ Aj" O\r -A?G\rA!@ (ì" M@ !  !  \nAkO\r  Aj" \n \nI"M@  j/A¿üF\r@@ Aj! Aj" K\r " j/A¿üG\r  !  \nI Aj"Kq  Atj"(! (!  6ì ( ! @ M\r -A!G\r  j-AßqAÁkAÿqAK\r@ Aj" O\r@  j-AßqAÁkAÿqAK\r Aj" G\r ! A! (ð" K  \nAkOq\r Aj" \n \nI"M@  j-A>F\r@@ Aj! Aj" K\r " j-A>G\r  !  \nI Aj" Kq  Atj"(! (!  6ð ( ! @ A j" O\r )B¼ÂìšÄ¨ªÁ… 1Bۅ„BR\rA! (ô" K  \nAkOq\r@ Aj" \n \nI" M@  j"/Aݺs -A>srE\r@@ Aj! Aj" K\r  "j"/Aݺs -A>sr\r  !  \nI Aj"Kq@  Atj"(! (!  6ô ( !\n ! Aj" \nO\r@ Aj" \nO\r  j-" A0kAÿqA\nIA AßqAÁkAÿqAI E\r@  j-"A0kAÿqA\nI\r AßqAÁkAÿqAI\r A+k"AK\r AF\r Aj" \nF\r@  kA K\r  j-" A:F@  \nO\r@  j-" A k"AMAA tA€€q\r A>G@ A I\r AG\r  j-A-F\rAð! Aj !@@ (x" (|"N@ AÀ Av j AL"6| (t Als"\rA! ($"\rE\rAå (, \r  Aj6x (t"E\r  6t (x"Aj6x  Alj" Ar: A<: B7  6  6@@ (x" (|"N@ AÀ Av j AL"6| (t Als"\rA! ($"\rE\rAå (, \r  Aj6x (t"E\r  6t (x"Aj6x  Alj" Ar: A>: B7  6  Ak6 (t (x"Alj"A k Ak6 Ak Ak6 ! !   6 @@ (x" (|"N@ AÀ Av j AL"6| (t Als"E\r 6t (x"Aj6x  Aj6x (t"E\r\n  Alj"A¼(; B7  6  6@ (x" (|"N@ AÀ Av j AL"6| (t Als"E\r 6t (x"Aj6x  Aj6x (t"E\r\n ( !  Alj"A¾0; B7  6  6 (t (x"Alj"A k Ak6 Ak Ak6A! !  (M\r@@   jAv"Atj"( K@ E@ ! \n   AtjAk(K@ ! \n Ak!  ( O@ ! Aj!  M\r A!  ($"E\rAå (,   Aj!  A F\r A F\r A\rkA}K\r AÿG AúKq A!kAI A:kAIr AÛkAIrr "! As! A! @  \nF\rA!A!@@  \nj" ( \nk"A7"AÿM@ A G\r  @@@  jAm"AtA°j(" Au j" AtA°j(Aÿÿÿq K@ Ak!   AvAq j"AtA°j(AÿÿÿqM\r Aj!  N\r  A! AH\r  A F\r A kAI\r A!Aä!AA  A7"AÿM@ AÿG AúKq A!kAI A:kAIr AÛkAIrr  @@@  jAm"AtAÀ:j(" Au j" AtAÀ:j(Aÿÿÿq K@ Ak!   AvAq j"AtAÀ:j(AÿÿÿqM\r Aj!  N\r A! AN "! As! ! \n!A   q AßFq""A " rE\r  kAp!@@ (x" (|"N@ AÀ Av j AL"6| (t Als"\rA! ($"\rE\rAå (, \r  Aj6x (t"\r  6t (x"Aj6x  Alj" AtA# AG  MqAA  OA r" AFrA@k:  : B7  \n6  6 ! \n "M\r@@@ (x" (|"N@ AÀ Av j AL"6| (t Als"\rA! ($"\rE\r Aå (, \r Aj6x (t"\r  6t (x"Aj6x  Alj"AÄ; B7  6  6 Aj" \nI\r ! \n! @@ (x"\r (|"N@ AÀ Av j AL"6| (t Als"\rA! ($"\rE\rAå (, \r  \rAj6x (t"E\r  6t (x"\rAj6x (!  \rAlj"Aÿ ; B7  6  6A!  A! Aj$@ " \r A (xA¿AM@ (à"AN@ Ak! A€j! AØj! A j!@ (t" Al"j" (!\r@ -"AÄF\r ( !\nA! A! \rAN@   \rAlj" ( Alj! \nAl! (! -A q@ A!: Ak"6A!!  j!  I@ ( I\r  I@ ( I\r @  I@ A!G\r  AÛG\r ( A€€ÀqE\r (" (O\r ( j-AÞG\r Aj"6 (t j"(" M\r  ( j  kN"E\r ( "E@ (pAj"6p  6  (Aj6 6 (6 -A”r:  -A˜r: (! (! (  @@@@ -\rA qE\r -AÛG\r E\r (" ("kAG\r -AÛG\r E\r ( ("kAG\r -AÝG\r  AkG\r ( ("kAG\r  (AjG\r@@ Aj" \nN"@ !  (t! !@@  Alj" -"AÄF\r AüF\r ( kAäK\r -AqE\r ( ! Aj" \nH\r A!  (" F\r  kAäK\r  I@ (!@@  j-A\nk Aj" G\r A!@   Atj"("L@ (t!\r@ \r Alj( " N\r  6  ("L@ (t!\r@ \r Alj( " N\r  6 Aj"AG\r @@ ( (I@@  L\r  kAk! (t!\rA!  AsjAq"@@ \r AljAÄ; Aj! Aj" G\r AI\r@ \r Alj"AÄ;L AÄ;8 AÄ;$ AÄ; Aj" G\r -Ar: (6  @ \r \n kAk! (t!\rA! \n AsjAq"@@ \r AljAÄ; Aj! Aj" G\r AI\r@ \r Alj"AÄ;L AÄ;8 AÄ;$ AÄ; Aj" \nG\r  (6 (6  (6 (t"\r j" \n6 \r j"\r 6  -Ar: \r \r-Ar: (! (!  Aj \nO (  (6  (6 (t"\r j" \n6 \r j"\r 6  -Ar: \r \r-Ar: (! (! (  \r (!  (" ("G\r ( AjK@ -AÀq\r    ( AjP  -AÀq\r   (  AjP "AH\r E\r  (6 (t \rAlj(!\r  @  ("O\r (" j-A(G\r \nAj! A! !@@@   jAv"Atj"( K@ E\r  AtjAk( I\r Ak!   (M\r Aj!  O\r A! @@ Aj"  Atj(" I@@  j-A k"AK\rA tA€€qE\r Aj" G\r !  6@  O\r  j-A\nk Aj" O\r  Atj(!  6 @  O\r  j-A)G\rA! A6 B7  6  6 Aj! A    Atj"(" Aj Aj 8E\r@   k ( Aj A j A,j A(j A$j9@ ( " j! (," F!   j"Atj(! (!   ("6(  6$A!A! @  I@@  j-"A k"AK\rA tA€€qE\r Aj" G\r Aj" O\r   Atj("j-! AÿqA)G\r  Aj" 6 ($" (("M@A! A6 B7A   k! @ A6  6   j"6A  @ q"@  Atj!A! !@   Atj("  K" KA!  "kAq"@@  ( j-: Aj! Aj! Aj" G\r  kA|M@@  ( j-:  ( j-:  ( j-:  ( j-: Aj! Aj" G\r   O\r A\n: Aj!  Aj"Atj(! ($" E\rAÔ (,   A6  6   k6 (! A ! (x" L@  6  (t! !@  Alj"(K@@ -AqAG\r  ( "Alj( I\r \r r  Aj" H\r  6  L\r  \nkAk! (t! A!  \nAsjAq"@@ AljAÄ; Aj! Aj" G\r AI\r@ Alj"AÄ; AÄ;L AÄ;8 AÄ;$ Aj" G\r  -AÀq\r   ( ( AjP"AH\r E\r -Ar:  -Ar: Aj" (tj (6 (t j ( 6  (tj (6( Aj! (t! (@  Alj (Ð6 6Ð  Alj (6 (! (! -!  Aj \nO   AÛF"!   !   !   ! ! / AŒqE\r@@ "Aj! -$"AÄG" \r  I\r À! !@@ "\nAk! \r  K\r -%" AqE\r E\r ( (G\rA÷ ATE\r (  (tkAmG\r \nAk( (G\r AÄ:$  Aïq:% \nAkAÄ: \nAk" -Aïq: \r "AN\r B7à A6¸ @A! A6Ô (x"AL\r (t!\rA!@@ \r Alj"-"Aq\r -AüG\r ( (kAG\r A6  Ar:@ (ØAH@ 6Ø  \r (ÜAlj 6 6Ü Aj"6Ô Aj" G\r A!  A! A (xO  A! A0j$ Þ#Aðk"$ B7h B7` B7X B7P B7H B7@ B78 B70 A6( B7 B7 B7 B7A! @    Aj AÐj<\r  A Aj A0j<\r  6( (,! @  Aj (" E@A!  ($"E\rA (,    Aj (" E@A!  ($"E\rAæ (,  (`@ (Pr (Tr (Xr (@@ (0r (4r (8r Aðj$ Ý@ ( " ("I@ (!  ( Av jA "At"s"E@A ($"E\rAå (, A  6 ( Ajs"E@A ($"E\rAå (, A  6  6 ( ! ( Atj 6  ( Atj 6  ( Aj6 A Ü Aj!@@@ Aj" O\r j-A#G\r j-A rAøG\r !@@@@ j-"A0kAÿqA\nI\r AÁkAÿqAI\r  kAK\r AákAÿqAI\r   kAK\r Aj" G\r !  F\r  kAI\r  @ Aj" O"\r j-A#G\r !@@  kAK\r j-A0kAÿqA K\r Aj" G\r !  F\r  kAI\r   M\r j-AßqAÁkAÿqAK\r  \r@@ j-"AßqAÁkAÿqAO@   kA0K\r A0kAÿqA\nI\r    kA0M\r   Aj" G\r  " kAkA.K\r  M\r j-A;G\rA!  Aj6  ³#Ak"$@@  O\r (!@  j-A k"AK\rA tA€€qE\r Aj" G\r !   O\r (!@  jAk-A k"AK\rA tA€€qE\r Ak" K\r !  6  6  6@  Aj (, ("@ ($"E\rAŠ (,   AjA?"\r  Aj (, ("E@A!  ($"E\rA¯ (,  Aj$  Ê"#A0k"\r$  H@ A¸j! A€j! \rAr! \rAr! (!@@ (t" Al" j"-"Aq@ AqE\r@ E\r ,"E\r  `\r ( !  ,"\nAÿq"E\r  \n`E\r (" I\r@@@@@@@@@@@@@@@@@ A!k^  (! Aq@ AN@  Alj" -AÀr:  6  6  AH\r  Alj"( 6¸  6  6@ (ä" AN@  Alj 6  6à 6ä A6  Aj" (xN\r  Alj"-A;G\r (  (" \rKE\r  6  6  Ar:  -Ar:  6  AqE\r \r A€A˜ \nA*Fj"A j6 AÀq" AÀF@ ! A  \r Aj6 A€F\r ! A ! Aj6A! A°A´ ( kAFj!\n@ AqE\rA! \n("AH\r@   Atj"\n("L@@  Alj( " N\r \n 6  \n("L@@  Alj( " N\r \n 6 Aj" AG\r  Alj" 6  6  -Ar:  -Ar: \r AqE\r  \n(6 \n 6 @ AqE\rA! (Ä"AH\r@   Atj"\n("L@@  Alj( " N\r \n 6  \n("L@@  Alj( " N\r \n 6 Aj" AG\r  Alj" 6  6  -Ar:  -Ar: AqE\r  (Ä6 6Ä @ AqE\r (¼"AH\rA!  Alj" ( (k ( kG\r@   Atj"\n("L@@  Alj( " N\r \n 6  \n("L@@  Alj( " N\r \n 6 Aj" AG\r @ Aj" N\r  kAk!A!  AsjAq"\n@@  AljAÄ; Aj! Aj" \nG\r AI\r@  Alj" AÄ;L AÄ;8 AÄ;$ AÄ; Aj" G\r 6  6 -Ar:  -Ar: A6¼ AqE\r\n  (¼6 6¼ \n  Aj"Al"j"(! (! \r 6 \r ("6, \r 6( \r 6$ \nAÀF@   \rAAAA˜ \rA(jRAL\r\n \r(!  O\r Q" AÿM\rA!A!@@@  jAm" AtA°j("Au j"AtA°j(Aÿÿÿq K@ Ak!  AvAq j"AtA°j(AÿÿÿqM\r Aj!  N\r  AN\r  ( kAG\r@ AqE\rA! (À"AH\r@   Atj"\n("L@@  Alj( " N\r \n 6  \n("L@@  Alj( " N\r \n 6 Aj" AG\r  Alj" 6  6  -Ar:  -Ar: AqE\r  (À6 6À  ( kAG\r@ AqE\rA! (È"AH\r@   Atj"\n("L@@  Alj( " N\r \n 6  \n("L@@  Alj( " N\r \n 6 Aj" AG\r  Alj" 6  6  -Ar:  -Ar:  AqE\r  (È6 6È  ( kAG\r@ AqE\rA! (Ì"AH\r@   Atj"\n("L@@  Alj( " N\r \n 6  \n("L@@  Alj( " N\r \n 6 Aj" AG\r  Alj" 6  6  -Ar:  -Ar:  AqE\r  (Ì6 6Ì  A! A!  A F\r A F\r A kAI\r ( jAk,"@Aã AT\r \r((" I\r Ak!@@@ -AÄF\r ( K\r  (O\r -" Aq\r Ak" O\r  AqE\r   \rA,jAA.AAØ \rA$jRAH\r \r(,! @ \nAÀF\r@ O\r (" j-A/G\r Aj  \rA,jAA/AùA \rA$jRAH\r \r(," O\r  j-A/G\r \r Aj" 6, @ O\r ( j-A?G\r Aj  \rA,jAA&AóA• \rA$jRAH\r \r(,! O\r ( j-A#G\r Aj  \rA,jAAAAÛ \rA$jRAH\r \r(,! @ O\rA!A!@ ( j" ( kA7"AÿM@ A F\r A F\r A kAO\r  @@@  jAm" AtA°j("Au j"AtA°j(Aÿÿÿq K@ Ak!   AvAq j"AtA°j(AÿÿÿqM\r Aj!  N\r  AN\r ,"@A¡ A T\r \r($"  (xAlj"O\r@@@ -AÄF\r ( M\r ( K\r -"Aq\r Aj" I\r  AqE\r  6  6  \n:  6  6 (t" j" 6  j" 6  -Ar:  -Ar:  \r Atr 6 A q! Aj! AàqAàG@ \r Atj Aj6 Aj! As AGqE@ \r Atj Aj6 Aj!  \r(("AljA AN"! A !@ \r(("AH\r  Alj! @ ( (M\r ! ! @ AF\r@ \r(("AH\r  Alj! @ ( (M\r ! ! AF\r@ \r( ("AH\r  Alj! @ ( (M\r ! ! AF\r@ \r(("AH\r  Alj! @ ( (M\r ! ! AF\r \r((" AH\r  Alj! @ ( (M\r ! ! E\r (! (! (! !\n@@@@@@  Alj"-"A!k\n AÛk A€A˜ A*Fj -"AtAuA qj!\n@ AvAk \nAj!\n  A°A´ ( (kAFj!\n  \nAj!\n @ k" k"K@  (" (k k j"Al" j" (6  )7  )7  k"6  6 (t j \n(6 \n 6  O\r  Alj j" (6  )7  )7  k j"6  6 A!\n@   \nAtj"("L@@ AN@  (t Alj( "6  N\r \nAj"\nAG\r (t" Alj" 6  j" 6  -Ar:  -Ar:  AqE\r A€A˜ \nA*Fj AtAuA qj!@@@ AvAk Aj!  Aj!  (6  6 -"AqE\r Aq@ (t ( Alj(!  (! Aj" H\r \rA0j$ –#Ak"$@ (E\r  6! (  (pAtj("E@A!  @  ("I\r   ( (ljO\r  (F@ ( (  DE\r A!   6  6  6  Aj6 Aj!@ ("@@   Av"Atj"G"AH@   E\r Aj!  Asj "\r A! E@A!  (! Aj$  ý#A k"$ Aß: A¦Ô;A! ( "A€ q@ A$:A! A€€€q@ Aj rA=: Aj! A€€€q@ Aj rA+: Aj! A€€q@ Aj jAü: Aj! A€€q@ Aj jAÞ: Aj! A€„q@ Aj jAþ: Aj! A! Aj jA:    AjAM ( "AŒq@ Aq@ AÀ:A! Aq@  rA:: Aj! A€q  rA.: Aj  rA:     AjM A€jAÿAÐü A j$ • (TE@A Ak! Ak!AA ("\n j-A!F j!A!@@@   jAv"Atj" ( K@ E\r  AtjAk( I\r Ak!   (M\r Aj!  O\r A! @  ("M" E@@  kq"@ !@    K" KA!  "kAq"\n@@  ( j-: Aj! Aj! Aj" \nG\r  kA|M@@  ( j-:  ( j-:  ( j-:  ( j-: Aj! Aj" G\r   O\r A : Aj! Aj" Atj"(! (! A! ($"E\rAÔ (, A  k   \nj!  k ! A  Aj60A! Aj !\nA!@@ \n("E\r Aj p"AH\r   kK\r \nAj!\n  j" I\r A=! AH\r A \r  l E@A!  A! (0!\n@ \n(" E\r Aj p" j" K\r Aj h \nAj!\n  K\r A \r  A€Àsl \r   \rH!   AHq\r A=! +0 \r  m"AN\r \n -!\n Aj! \r E\rA!@  Atj("\n@  Atj \n jA! Aj"A\nG\r A\nO@A! \n @  Atj(\rA! Aj"A\nG\r A!   :\'A! ! !   k"  H" AÿÿÿÿsJ\rA=! \r  j"  \rH" \nK\r A   l  h A0   A€€sl A0  Al h A   A€Àsl ( Ak" O\r B€”ëÜT\r Ak" > @ "I@ Ak"(E\r (, k"6, ! AJ\r AH@ AjA nAj! AæF!@A A k" A O!\n@  M@AA (!  A€”ëÜ \nv!\rA \ntAs!A! !@  (" \nv j6  q \rl! Aj" I\r AA (! E\r  6 Aj! (, \nj"6,   j" " Atj   kAu J! AH\r A!@  M\r  kAuA l!A\n! ("A\nI\r@ Aj!  A\nl"O\r A AæGk AçF AGqk"  kAuA lA kH@ A0jA„`A¤b AHj A€Èj"A m"\rAtj!\nA\n!  \rA lk"AL@@ A\nl! Aj"AG\r @ \n("  n" lk"\rE \nAj" Fq\r@ AqE@D@C! A€”ëÜG\r \nO\r \nAk-AqE\r D@C! Dà?Dð?Dø?  FDø? \r Av"F \r I!@ \r -A-G\r š! š! \n  \rk"6    a\r \n  j"6 A€”ëÜO@@ \nA6 \nAk"\nK@ Ak" A6 \n \n(Aj"6 Aÿ“ëÜK\r  kAuA l!A\n! ("A\nI\r@ Aj!  A\nl"O\r \nAj"   K! @ " M"E@ Ak"(E\r @ AçG@ Aq!\r  AsA A " J A{Jq"\n j! AA~ \n j! Aq"\r\rAw!@ \r Ak("\nE\rA\n!A! \nA\np\r@ "\rAj! \n A\nl"pE\r \rAs!  kAuA l! A_qAÆF@A!\r  jA k"A AJ"  J!  A!\r  j jA k"A AJ"  J! A!\n AýÿÿÿAþÿÿÿ \rr"J\r AGjAj!@ A_q"AÆF@  AÿÿÿÿsJ\r A AJ!    Au"s k­ k"kAL@@ Ak"A0:  kAH\r Ak" : AkA-A+ AH:  k" AÿÿÿÿsJ\r  j" AÿÿÿÿsJ\r A   j" l  h A0   A€€sl@@@ AÆF@ AjA r!  K"! @ 5 k!@  G@  AjM\r@ Ak"A0:  AjK\r   G\r Ak"A0:   kh Aj" M\r @ AùAh  M\r AL\r@ 5 k" AjK@@ Ak"A0:  AjK\r A A Nh A k! Aj" O\r A J! ! \r  @ AH\r  Aj  K!\n AjA r! !@  5 k"F@ Ak"A0: @  G@  AjM\r@ Ak"A0:  AjK\r  Ah Aj! \rrE\r AùAh   k"  Hh k! Aj" \nO\r AN\r A0 AjAAl   kh  ! A0 A jA Al A   A€Àsl    J!\n   AtAuA qj!@ A K\rA k!D0@!@ D0@¢! Ak"\r -A-F@  š ¡ š!     ¡!  (," Au"s k­ k"F@ Ak"A0: (,! Ar!\r A q! Ak" Aj: AkA-A+ AH: AqE ALq! Aj!@ " ü"AÐÑj- r:  ·¡D0@¢!@ Aj" AjkAG\r Da q\r A.: Aj! Db\r A!\n Aýÿÿÿ \r  k" j"kJ\r A   Aj  Ajk" Ak H  "j" l  \rh A0   A€€sl Aj h A0  kAAl  h A   A€Àsl    J!\n A°j$ \n ¹~  (AjAxq"Aj6 )! )!#A k"$ Bÿÿÿÿÿÿ?ƒ!~ B0ˆBÿÿƒ"§"AøkAýM@ B† B<ˆ„! A€øk­!@ Bÿÿÿÿÿÿÿÿƒ"B€€€€€€€Z@ B|!  B€€€€€€€€R\r Bƒ |! B  BÿÿÿÿÿÿÿV"! ­ |  @  „P\r BÿÿR\r B† B<ˆ„B€€€€€€€„!Bÿ  Aþ‡K@B!Bÿ  A€øAø P"\n" k" AðJ@B!B   B€€€€€€À„ \n!A!\n G@ Aj! ! !@A€ k"AÀq@  A@j­†!B!  E\r  ­"† AÀ k­ˆ„!  †! 7 7 ) )„BR!\n @ AÀq@  A@j­ˆ!B!  E\r AÀ k­†  ­"ˆ„!  ˆ!  7  7 )B† )"B<ˆ„!@ \n­ Bÿÿÿÿÿÿÿÿƒ„"B€€€€€€€Z@ B|!  B€€€€€€€€R\r Bƒ |! B€€€€€€€…  BÿÿÿÿÿÿÿV"! ­ ! A j$ B€€€€€€€€€ƒ B4†„ „¿9 ¦ (T"(! (" ( ("k"  I"@   V  ( j"6  ( k"6    K"@   V  ( j"6  ( k6 A: (,"6 6  ¢ E@A @  AÿM\r@AìÞ((E@ A€qA€¿F\rAÐÝA6  AÿM@ A?qA€r: AvAÀr:A  A€@qA€ÀG A€°OqE@ A?qA€r: A vAàr: AvA?qA€r:A  A€€kAÿÿ?M@ A?qA€r: AvAðr: AvA?qA€r: A vA?qA€r:A  AÐÝA6 AA  :A Ñ( #Ak"\n$@@@@@@@@@@ AôM@Aß("A A jAøq A I"Av"v"Aq@@ AsAq j"At"A¸ßj" (À_"("F@Aß A~ wq6   6 6 Aj!  Ar6  j" (Ar6 A˜ß("M\r @@ tA t"A krqh"At"A¸ßj" (À_"("F@Aß A~ wq"6   6  6 Ar6 j"  k"Ar6 j 6 @ AxqA¸ßj!A¤ß(! A Avt"qE@Aß  r6   ( !  6  6  6  6 Aj!A¤ß 6A˜ß 6 A”ß(" E\r hAt(Àa"(Axq k! !@@ ("E@ ("E\r (Axq k"   K"!  ! !  (!  ( "G@ (" 6 6 \n (" Aj ("E\r Aj !@ ! "Aj! ("\r Aj! ("\r A6 A! A¿K\r A j"Axq!A”ß(" E\rA! AôÿÿM@ A& Avg"kvAq AtkA>j! A k!@@@ At(Àa"E@A!  A! A AvkA AGt!@@ (Axq k" O\r ! "\rA! !  ("   AvAqj("F ! At! "\r rE@A!A t"A kr q"E\r hAt(Àa! E\r @ (Axq k" I!   !  ! ("  ( "\r E\r A˜ß( kO\r (!  ( "G@ (" 6 6  (" Aj ("E\r Aj !@ ! "Aj! ("\r Aj! ("\r A6  A˜ß("M@A¤ß(!@ k"AO@  j" Ar6 j 6  Ar6   Ar6 j" (Ar6A!A! A˜ß 6A¤ß 6 Aj! Aœß("I@Aœß  k"6A¨ßA¨ß(" j"6  Ar6 Ar6 Aj! A! A/j"Aèâ(@Aðâ(  AôâB7AìâB€ €€€€7Aèâ \nA jApqAتժs6AüâA6AÌâA6A€ "j"A k"q" M\rAÈâ("@AÀâ(" j" M\r  I\r @AÌâ-AqE@@@@@A¨ß("@AÐâ!@ (" M@   (jI\r ("\r Au"AF\r !Aìâ("Ak" q@  k  jA kqj!  O\rAÈâ("@AÀâ(" j" M\r I\r u" G\r   k q"u" ( (jF\r ! AF\r A0j M@ !  Aðâ("  kjA kq"uAF\r  j! !  AG\r AÌâAÌâ(Ar6 u!Au! AF\r AF\r M\r k" A(jM\r AÀâAÀâ( j"6AÄâ( I@AÄâ 6 @A¨ß("@AÐâ!@  (" ("jF\r ("\r  A ß("A ME@A ß 6 A!AÔâ 6AÐâ 6A°ßA6A´ßAèâ(6AÜâA6@ At" A¸ßj"6À_  6Ä_ Aj"A G\r Aœß A(k"Ax kAq"k"6A¨ß  j"6  Ar6 jA(6A¬ßAøâ(6   O\r  I\r ( Aq\r  j6A¨ß Ax kAq"j"6AœßAœß( j" k"6  Ar6  jA(6A¬ßAøâ(6  A!  A!  A ß( K@A ß 6  j!AÐâ!@@  ("G@ ("\r  - AqE\r AÐâ!@@ (" M@   (j"I\r (!  Aœß A(k"Ax kAq"k"6A¨ß  j"6  Ar6 jA(6A¬ßAøâ(6  A\' kAqjA/k" AjI"A6 AØâ)7 AÐâ)7AØâ Aj6AÔâ 6AÐâ 6AÜâA6 Aj!@ A6 Aj! Aj!  I\r  F\r  (A~q6   k"Ar6  6 AÿM@ AøqA¸ßj!Aß("A Avt"qE@Aß  r6  ( ! 6  6 A !A  A! AÿÿÿM@ A& Avg"kvAq AtrA>s!  6 B7 AtAÀáj!@@A”ß("A t"qE@A”ß  r6  6  6  A AvkA AGt! (!@ "(Axq F\r Av! At!  Aqj"("\r  6  6 A! ! !A  (" 6  6  6A!A!A j 6  j 6 Aœß(" M\rAœß k"6A¨ßA¨ß(" j"6  Ar6 Ar6 Aj!  AÐÝA06A!  6 ( j6 Ax kAqj" Ar6 Ax kAqj"  j"k!@A¨ß( F@A¨ß 6AœßAœß( j"6  Ar6  A¤ß( F@A¤ß 6A˜ßA˜ß( j"6  Ar6  j 6  ("AqAF@ Axq! ( !@ AÿM@ (" F@AßAß(A~ Avwq6  6  6  (!@  G@ (" 6  6  @ (" Aj ("E\r Aj !@ ! "Aj! ("\r Aj! ("\r A6  A! E\r@ ("At"(Àa F@ AÀáj 6 \rA”ßA”ß(A~ wq6  @  (F@  6   6 E\r  6 ("@  6  6 ("E\r  6  6  j"(!  j!  A~q6  Ar6  j 6 AÿM@ AøqA¸ßj!Aß("A Avt"qE@Aß  r6   ( !  6  6  6  6  A! AÿÿÿM@ A& Avg"kvAq AtrA>s!  6 B7 AtAÀáj!@@A”ß("A t"qE@A”ß r6  6  6  A AvkA AGt! (!@ "(Axq F\r Av! At!  Aqj"("\r  6  6  6  6  (" 6  6 A6  6  6 Aj!  @ E\r@ ("At"(Àa F@ AÀáj 6 \rA”ß A~ wq" 6  @  (F@  6   6 E\r 6 ("@ 6  6 ("E\r 6  6 @ AM@   j"Ar6 j" (Ar6   Ar6  j" Ar6  j 6 AÿM@ AøqA¸ßj!Aß("A Avt"qE@Aß  r6  ( ! 6  6  6  6  A! AÿÿÿM@ A& Avg"kvAq AtrA>s!  6 B7 AtAÀáj!@@ A t"qE@A”ß  r6  6  6  A AvkA AGt! (!@ "(Axq F\r Av! At!  Aqj"("\r  6  6  6  6  (" 6  6 A6  6  6 Aj!  @ E\r@ ("At"(Àa F@ AÀáj 6 \rA”ß A~ wq6  @  (F@ 6  6 E\r 6 ("@ 6  6 ("E\r 6  6 @ AM@   j"Ar6 j" (Ar6   Ar6  j" Ar6  j 6 @ AxqA¸ßj!A¤ß(!A Avt" qE@Aß  r6   ( !  6  6 6 6 A¤ß 6A˜ß 6 Aj! \nAj$ ‚ @ E\r Ak" Ak("Axq"j!@ Aq\r AqE\r  ("k"A ß(I\r j!@@@A¤ß( G@ ( ! AÿM@  ("G\rAßAß(A~ Avwq6  (!  G@ (" 6  6  (" Aj ("E\r Aj !@ ! "Aj! ("\r Aj! ("\r A6  ("AqAG\rA˜ß 6  A~q6  Ar6  6  6  6  A! E\r@ ("At"(Àa F@ AÀáj 6 \rA”ßA”ß(A~ wq6  @  (F@  6   6 E\r  6 ("@  6  6 ("E\r  6  6  O\r ("AqE\r@@@@ AqE@A¨ß( F@A¨ß 6AœßAœß( j"6  Ar6 A¤ß(G\rA˜ßA6A¤ßA6 A¤ß(" F@A¤ß 6A˜ßA˜ß( j"6  Ar6 j 6 Axq j! ( ! AÿM@ (" F@AßAß(A~ Avwq6   6  6  (!  G@ (" 6  6  (" Aj ("E\r Aj !@ ! "Aj! ("\r Aj! ("\r A6   A~q6  Ar6 j 6  A! E\r@ ("At"(Àa F@ AÀáj 6 \rA”ßA”ß(A~ wq6  @  (F@  6   6 E\r  6 ("@  6  6 ("E\r  6  6  Ar6 j 6  G\rA˜ß 6 AÿM@ AøqA¸ßj!Aß("A Avt"qE@Aß r6   ( !  6 6  6  6 A! AÿÿÿM@ A& Avg"kvAq AtrA>s!  6 B7 AtAÀáj!@A”ß("A t"qE@A”ß  r6  6A!A  A AvkA AGt! (!@ "(Axq F\r Av! At!  Aqj"("\r  6A! !A ! !   (" 6  6A!A!A !  j 6  6 j 6A°ßA°ß(Ak"A 6 ‰  E@ q A@O@AÐÝA06A A A jAxq A I! Ak"("Axq!@ AqE@ A€I\r Aj M@ !  kAðâ(AtM\r A   j!@  O@  k"AI\r   AqrAr6  j" Ar6  (Ar6  t  A¨ß( F@Aœß( j" M\r   AqrAr6  j"  k"Ar6Aœß 6A¨ß 6  A¤ß( F@A˜ß( j" I\r@  k"AO@   AqrAr6  j" Ar6  j" 6  (A~q6   Aq rAr6  j" (Ar6A!A! A¤ß 6A˜ß 6  ("Aq\r Axq j"\n I\r \n k! ( !@ AÿM@ (" F@AßAß(A~ Avwq6   6  6  (! @  G@ (" 6  6  @ (" Aj ("E\r Aj !@ ! "Aj! ("\r Aj! ("\r A6  A! E\r@ ("At"(Àa F@ AÀáj 6 \rA”ßA”ß(A~ wq6  @  (F@ 6  6 E\r  6 ("@  6  6 ("E\r  6  6 AM@  Aq \nrAr6  \nj" (Ar6    AqrAr6  j" Ar6  \nj" (Ar6  t !  "@ Aj q"E@A  A|Ax Ak("Aq Axqj"   KV r  «  j!@@ ("Aq\r AqE\r (" j!@@@ k"A¤ß(G@ ( ! AÿM@  ("G\rAßAß(A~ Avwq6  (! G@ (" 6  6  (" Aj ("E\r Aj !@ ! "Aj! ("\r Aj! ("\r A6  ("AqAG\rA˜ß 6  A~q6 Ar6  6  6  6  A! E\r@ ("At"(Àa F@ AÀáj 6 \rA”ßA”ß(A~ wq6  @ (F@  6   6 E\r  6 ("@  6  6 ("E\r  6  6 @@@@ ("AqE@A¨ß( F@A¨ß 6AœßAœß( j"6 Ar6 A¤ß(G\rA˜ßA6A¤ßA6 A¤ß(" F@A¤ß 6A˜ßA˜ß( j"6 Ar6 j 6 Axq j! ( ! AÿM@ (" F@AßAß(A~ Avwq6   6  6  (!  G@ (" 6  6  (" Aj ("E\r Aj !@ ! "Aj! ("\r Aj! ("\r A6   A~q6 Ar6 j 6  A! E\r@ ("At"(Àa F@ AÀáj 6 \rA”ßA”ß(A~ wq6  @  (F@  6   6 E\r  6 ("@  6  6 ("E\r  6  6 Ar6 j 6 G\rA˜ß 6 AÿM@ AøqA¸ßj!Aß("A Avt"qE@Aß  r6   ( !  6  6 6 6 A! AÿÿÿM@ A& Avg"kvAq AtrA>s! 6 B7 AtAÀáj!@@A”ß("A t"qE@A”ß  r6  6 6  A AvkA AGt! (!@ "(Axq F\r Av! At!  Aqj"("\r  6 6 6 6 (" 6  6 A6 6 6 W~@ ­B|BøÿÿÿƒAÄÜ("­|"BÿÿÿÿX@ §"?AtM\r \r AÐÝA06A AÄÜ 6  ² #Ak"$  6 @ AÓM@AàÑA Ó A jx(!  A|O@y  AÒn"AÒl"k6A ÓAàÔ Ajx"( j! A ÓkAu!@A!@@@ "A/F\r At(àQ"n" I\r Aj!  lG\r A/I\r AÓ!@ n" I\r  lF\r A\nj"n" I\r  lF\r A j"n" I\r  lF\r Aj"n" I\r  lF\r Aj"n" I\r  lF\r Aj"n" I\r  lF\r Aj"n" I\r  lF\r Aj"n" I\r  lF\r A$j"n" I\r  lF\r A(j"n" I\r  lF\r A*j"n" I\r  lF\r A.j"n" I\r  lF\r A4j"n" I\r  lF\r A:j"n" I\r  lF\r A`-_.-+_\\\\({[,"children":[NANINFcatching a class without an object?)}].!?,;mailto:,"content":h6h5h4h3h2h1http://Too many link reference definition instantiations.Unsupported abi_version.Aborted from text() callback.Aborted from enter_span() callback.Aborted from leave_span() callback.Aborted from enter_block() callback.Aborted from leave_block() callback.malloc() failed.realloc() failed.@:..!#$%&\'*+/=?^_`{|}~-_.:-+-.-_+-_*(null)Suppressing too sparse table (see https://github.com/mity/md4c/issues/345)._=().+-_~%false && "unhandled NodeType in nodeTypeToString"\\"{"type":"[]!xX \n™Jìi¿e£<‡ ¢°üOs{±2‡+F< ÂÎ._VÉšAÜ ~ô H, „*NSt3__220__shared_ptr_emplaceIN8Markdown15MarkdownASTNodeENS_9allocatorIS2_EEEE8™(A€ ä A  f\r0\r`\r\r\rÐ\r\rp\r\r€ Àà\r\r @ \r\r\r\rA UmŒA° !þ\n-Aà Á™ÅA 5¨]¸‹;OAÐ 5F¾\n&’îa=A MM J G D A > ¬¨Að `A€ •EA  ܘóAÀ \r”nAà ¼¨A€ \r’A  ±Ô$AÀ Eu,’Ø–«gYA  A  ”A° —  € @\n €/ _ 0A@Z€µÀ@րØ@ހ@.€2@6€9@G€J@v€xy@}€‚„†‡‰Š‹Ž‘“”–—˜œŸ @¤€¦§©¬®¯±²³µ·¸¼ÄÅÇÈÊË@Û€Þ@î€ñòôö÷ø@€ "@2€:;=>ACDEF@N€Eprv†ˆ@Š€ŒŽ‘@¡€£@«€ÂÏÐÑÕÖØ@î€ðñôõ÷ùúý@ÿ€@€@/€`@€€Š@¾€ÀÁ@Í€Ð@.€1@V€ @Å€ÇÍø@ý€€‚ƒ„…†‡ˆ‰@º€½@¿€@”€› @þ€@€@€(@/€8@?€H@M€Y[]_h@o€¸¹º»¾È@Ë€ØÙÚÛèéêëìøùúû&!*!+!2!`!@o!€ƒ!¶$@Ï$€,@/,€`,b,c,d,g,@k,€m,n,o,p,r,u,~,,€,@â,€ë,í,ò,@¦@l¦€€¦@š¦€"§@.§€2§@n§€y§{§}§~§@†§€‹§§§’§–§@¨§€ª§«§¬§­§®§°§±§²§³§´§@§€Ä§Å§Æ§Ç§É§Ë§Ì§@Ú§€Ü§Ý§â§õ§l«m«p«@¿«€!ÿ@:ÿ€@\'€°@Ó€p@z€|@Š€Œ@’€”•€ @² €P\r@e\r€ @¿€@n@_n€ n@¸n€@ßHßJßMßQßhß@n߀rß@~߀é@!é€az¼àöøþ/37:HKwÿz~sSƒ…TˆVWŒÝY[’`cih™oru¡¥€¨ƒ­ˆ°Š‹´¶’¹½ÆÆÉÉÌÌÜßïóóõ•¿ùž#3e,<šf,B€‰ŒGO¹qswó¬­¯ÌÍαÁÃËÃײ¸ÆÀÙïºÁ¸µøòû{}P_0Oa‹¿ÏÂÎÑ/a†-%-\'---ðõ24>ABBJcK¦ŠÐúýÿ•a¡ÿ \'07@EQSUW`g°±pq¹ruÐÑvwàáz{åxy|}ÉkåN!p!!„!Ð$é$0,_,a,k}}h,l,QqPRs,v,?@,ã,ì,î,ó,A¦m¦¦›¦#§/§3§o§z§|§y§‡§Œ§e‘§“§—§©§f\\aljž‡S«µ§Ã§”§‚Žȧʧdͧۧ›w|ö§K«L« ïAÿZÿ(OØû—¡£±³¹»¼À ò p\r…\rÀß`nn»nÓnAßIßKßNßRßißoßsßß"éCéAÐ2 Óß0Ið‡–—˜™šžP€@‡€ˆ@€@—€˜@Ÿ€ @§€¨@¯€²³´¶¼ÂÃÄÆÌÖäæòóôöüûûûûûûûûûû•ßA°4 ¥ssi¼nj e‚h1tw\ny\na¾ssʹ¹¹ ¹\'¹ ¹\'¹`¹g¹`¹g¹p¹±¹¬¹±B±¹t¹·¹®¹·B·¹¹BÁÅB|¹É¹Î¹ÉBɹfffiflststtvtetk~vtmssAà7 À°RTV·ÇÒÓ×âãç÷ûû¹ÅÅÅÅB±B¹·B¹¹¹¹BÅÅÅBÉB¹ffifflА.P05à  A´: ½!@/€:@@€[@`€{@~€¡@©€«@¬€®@±€´¶@¸€»¿×÷Â@Å€Ò@߀å@ë€íï@ÿ€u~„@…€‡ö‚Z@_€‰@Š€@€¾ÀÃÆó@ô€@€@€j@m€ÔÞéý@þ€@\r€ö@ù€þ@ÿ€0@>€^ˆd @e €p ò @ó €ú @û €ý v\nð\n@ñ\n€p ó @ú €w  „ O\ry\rô\r?OZ@[€@€@€468:@=€…¾@Å€Ç@Ì€Î@Ú€J@O€ž@Ÿ€û`@h€@™€m@n€›@œ€ë@í€5@6€Ô@Ö€Ø@Û€@\n€@D@E€Þ@ÿ€@€ @¦€¨@­€N@O€Z@j€t@€ü@ÿ€;@?€~@€À@Ç€Ó½¿@Á€Í@Ï€Ý@߀í@ï€ý@þ€ @\' €0 @^ €z @~ €Š @Ž €  @Ä €!@!€!@!€!@ !€!!@!€!@#!€%!\'!)!.!:!@;!€@!@D!€J!@M!€O!Š!@‹!€!@)$€@$@J$€œ$@é$€%@u\'€”\'@s+€v+@ÿ+€å,@ê,€ù,@ü,€þ,@ÿ,€p-.@..€0.@].€`.@c.€€.@™.€›.@ó.€/@Õ/€ð/@ÿ/€0@0€0@ 0€0060@70€=0@?0€›0@œ0€ 0û01@‘1€–1@Ÿ1€À1@å1€ï12@2€*2@G2€P2`2@2€Š2@°2€À2@ÿ3€ÀM@ÿM€¤@Ƥ€þ¤@ÿ¤€\r¦@¦€s¦~¦ò¦@÷¦€§@§€ §@!§€‰§@Ч€(¨@+¨€6¨@9¨€t¨@w¨€Î¨@Ϩ€ø¨@ú¨€ü¨.©@/©€_©Á©@Í©€Þ©@ß©€\\ª@_ª€wª@yª€Þª@ߪ€ðª@ñª€[«j«@k«€ë«)û²û@Òû€>ý@Oý€ý@‘ý€Èý@Ïý€üý@ÿý€þ@þ€0þ@Rþ€Tþ@fþ€hþ@kþ€ÿ@ÿ€ÿ@ ÿ€;ÿ@@ÿ€[ÿ@eÿ€àÿ@æÿ€èÿ@îÿ€üÿ@ýÿ€@€7@?€y@‰€Œ@Ž€@œ€ Ð@ü€ŸÐoWw@x€ ? P\n@X\n€\nÈ\nð\n@ö\n€9 @? €™ @œ €n\rŽ\r@\r€­É@Ê€Ð@Ø€U@Y€†@‰€G@M€»@¼€¾@Á€@@C€t@u€Å@È€ÍÛÝ@߀8@=€©Ô@Õ€×@Ø€K@O€Z@[€]ÆÁ@×€A@C€`@l€¹<@?€;D@F€â?@F€š@œ€ž@¢€@ €áA@E€p@q€÷@ø€C@O€Õ@ñ€ÿp$@t$€ñ/@ò/€nj@oj€õj7k@?k€Dk@Ek€mm@om€—n@šn€âoœ¼Ÿ¼Ì@ïÌ€úÌ@üÌ€Í@³Î€ºÎ@Ð΀ÒÎ@Ô΀ÝÎ@ý΀PÏ@ÃÏ€Ð@õЀÑ@&Ñ€)Ñ@dÑ€jÑ@lÑ€ƒÑ@„Ñ€ŒÑ@©Ñ€®Ñ@AÒ€EÒSÒ@ZÒ€]Ò@^Ò€`Ò@Ò€Ó@VÓ€ÁÖÛÖûÖ×5×O×o׉ש×Ãר@ÿÙ€7Ú@:Ú€mÚ@tÚ€vÚ@ƒÚ€…Ú@‹Ú€Û@Û€Oáÿâÿå^é@_逬ì°ì.íðî@ñî€ð@+ð€0ð@“ð€ ð@®ð€±ð@¿ð€Áð@Ïð€Ñð@õð€\rñ@®ñ€æñ@ò€ò@;ò€@ò@Hò€Pò@Qò€`ò@eò€ó@Ùö€Üö@ìö€ðö@üö€÷@Û÷€à÷@ë÷€ð÷@ ø€ø@Gø€Pø@Yø€`ø@‡ø€ø@­ø€°ø@»ø€Àø@Áø€Ðø@Øø€ù@Wú€`ú@mú€pú@|ú€€ú@Æú€ÈúÌú@Ýú€ßú@ëú€ïú@úú€û@’û€”û@ïû€úû A€Î A  \n\n\n   AÑÎ ! \r\r  A‹Ï  A—Ï  AÅÏ AÑÏ  AÿÏ A‹Ð  AÂÐ  AóÐ AÿÐ  A­Ñ A¹Ñ € 0123456789ABCDEF \r%)+/5;=CGIOSYaegkmqƒ‰‹•—£§­³µ¿ÁÅÇÓ \r%)+/5;=CGIOSYaegkmqyƒ‰‹•—£§©­³µ»¿ÁÅÇÑ ,h*NSt3__214__shared_countE¤,œ*`*NSt3__219__shared_weak_countEAÄÕ ø\ndè\' †@B€–˜áõʚ;00010203040506070809101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899H,Ä+(.N10__cxxabiv116__shim_type_infoEH,ô+¸+N10__cxxabiv117__class_type_infoEè+ !"#$%&h,\'!"#()*H,t,è+N10__cxxabiv120__si_class_type_infoEÄ,+!"#,-.H,Ð,è+N10__cxxabiv121__vmi_class_type_infoEL-/0h-124-34 ,<-St9exceptionH,X-4-St9bad_allocH,t-L-St20bad_array_new_length¤-56H,°-4-St11logic_errorÔ-76H,à-¤-St12length_error.86H,.¤-St12out_of_range ,0.St9type_infoAÁÜ  1€')}function getBinarySync(file){return file}async function getWasmBinary(binaryFile){return getBinarySync(binaryFile)}async function instantiateArrayBuffer(binaryFile,imports){try{var binary=await getWasmBinary(binaryFile);var instance=await WebAssembly.instantiate(binary,imports);return instance}catch(reason){err(`failed to asynchronously prepare wasm: ${reason}`);abort(reason)}}async function instantiateAsync(binary,binaryFile,imports){return instantiateArrayBuffer(binaryFile,imports)}function getWasmImports(){var imports={env:wasmImports,wasi_snapshot_preview1:wasmImports};return imports}async function createWasm(){function receiveInstance(instance,module){wasmExports=instance.exports;assignWasmExports(wasmExports);updateMemoryViews();return wasmExports}function receiveInstantiationResult(result){return receiveInstance(result["instance"])}var info=getWasmImports();if(Module["instantiateWasm"]){return new Promise((resolve,reject)=>{Module["instantiateWasm"](info,(inst,mod)=>{resolve(receiveInstance(inst,mod))})})}wasmBinaryFile??=findWasmBinary();var result=await instantiateAsync(wasmBinary,wasmBinaryFile,info);var exports=receiveInstantiationResult(result);return exports}class ExitStatus{name="ExitStatus";constructor(status){this.message=`Program terminated with exit(${status})`;this.status=status}}var callRuntimeCallbacks=callbacks=>{while(callbacks.length>0){callbacks.shift()(Module)}};var onPostRuns=[];var addOnPostRun=cb=>onPostRuns.push(cb);var onPreRuns=[];var addOnPreRun=cb=>onPreRuns.push(cb);var noExitRuntime=true;var stackRestore=val=>__emscripten_stack_restore(val);var stackSave=()=>_emscripten_stack_get_current();var UTF8Decoder=globalThis.TextDecoder&&new TextDecoder;var findStringEnd=(heapOrArray,idx,maxBytesToRead,ignoreNul)=>{var maxIdx=idx+maxBytesToRead;if(ignoreNul)return maxIdx;while(heapOrArray[idx]&&!(idx>=maxIdx))++idx;return idx};var UTF8ArrayToString=(heapOrArray,idx=0,maxBytesToRead,ignoreNul)=>{var endPtr=findStringEnd(heapOrArray,idx,maxBytesToRead,ignoreNul);if(endPtr-idx>16&&heapOrArray.buffer&&UTF8Decoder){return UTF8Decoder.decode(heapOrArray.subarray(idx,endPtr))}var str="";while(idx>10,56320|ch&1023)}}return str};var UTF8ToString=(ptr,maxBytesToRead,ignoreNul)=>ptr?UTF8ArrayToString(HEAPU8,ptr,maxBytesToRead,ignoreNul):"";var ___assert_fail=(condition,filename,line,func)=>abort(`Assertion failed: ${UTF8ToString(condition)}, at: `+[filename?UTF8ToString(filename):"unknown filename",line,func?UTF8ToString(func):"unknown function"]);class ExceptionInfo{constructor(excPtr){this.excPtr=excPtr;this.ptr=excPtr-24}set_type(type){HEAPU32[this.ptr+4>>2]=type}get_type(){return HEAPU32[this.ptr+4>>2]}set_destructor(destructor){HEAPU32[this.ptr+8>>2]=destructor}get_destructor(){return HEAPU32[this.ptr+8>>2]}set_caught(caught){caught=caught?1:0;HEAP8[this.ptr+12]=caught}get_caught(){return HEAP8[this.ptr+12]!=0}set_rethrown(rethrown){rethrown=rethrown?1:0;HEAP8[this.ptr+13]=rethrown}get_rethrown(){return HEAP8[this.ptr+13]!=0}init(type,destructor){this.set_adjusted_ptr(0);this.set_type(type);this.set_destructor(destructor)}set_adjusted_ptr(adjustedPtr){HEAPU32[this.ptr+16>>2]=adjustedPtr}get_adjusted_ptr(){return HEAPU32[this.ptr+16>>2]}}var exceptionLast=0;var uncaughtExceptionCount=0;var ___cxa_throw=(ptr,type,destructor)=>{var info=new ExceptionInfo(ptr);info.init(type,destructor);exceptionLast=ptr;uncaughtExceptionCount++;throw exceptionLast};var __abort_js=()=>abort("");var getHeapMax=()=>536870912;var alignMemory=(size,alignment)=>Math.ceil(size/alignment)*alignment;var growMemory=size=>{var oldHeapSize=wasmMemory.buffer.byteLength;var pages=(size-oldHeapSize+65535)/65536|0;try{wasmMemory.grow(pages);updateMemoryViews();return 1}catch(e){}};var _emscripten_resize_heap=requestedSize=>{var oldSize=HEAPU8.length;requestedSize>>>=0;var maxHeapSize=getHeapMax();if(requestedSize>maxHeapSize){return false}for(var cutDown=1;cutDown<=4;cutDown*=2){var overGrownHeapSize=oldSize*(1+.2/cutDown);overGrownHeapSize=Math.min(overGrownHeapSize,requestedSize+100663296);var newSize=Math.min(maxHeapSize,alignMemory(Math.max(requestedSize,overGrownHeapSize),65536));var replacement=growMemory(newSize);if(replacement){return true}}return false};var getCFunc=ident=>{var func=Module["_"+ident];return func};var writeArrayToMemory=(array,buffer)=>{HEAP8.set(array,buffer)};var lengthBytesUTF8=str=>{var len=0;for(var i=0;i=55296&&c<=57343){len+=4;++i}else{len+=3}}return len};var stringToUTF8Array=(str,heap,outIdx,maxBytesToWrite)=>{if(!(maxBytesToWrite>0))return 0;var startIdx=outIdx;var endIdx=outIdx+maxBytesToWrite-1;for(var i=0;i=endIdx)break;heap[outIdx++]=u}else if(u<=2047){if(outIdx+1>=endIdx)break;heap[outIdx++]=192|u>>6;heap[outIdx++]=128|u&63}else if(u<=65535){if(outIdx+2>=endIdx)break;heap[outIdx++]=224|u>>12;heap[outIdx++]=128|u>>6&63;heap[outIdx++]=128|u&63}else{if(outIdx+3>=endIdx)break;heap[outIdx++]=240|u>>18;heap[outIdx++]=128|u>>12&63;heap[outIdx++]=128|u>>6&63;heap[outIdx++]=128|u&63;i++}}heap[outIdx]=0;return outIdx-startIdx};var stringToUTF8=(str,outPtr,maxBytesToWrite)=>stringToUTF8Array(str,HEAPU8,outPtr,maxBytesToWrite);var stackAlloc=sz=>__emscripten_stack_alloc(sz);var stringToUTF8OnStack=str=>{var size=lengthBytesUTF8(str)+1;var ret=stackAlloc(size);stringToUTF8(str,ret,size);return ret};var ccall=(ident,returnType,argTypes,args,opts)=>{var toC={string:str=>{var ret=0;if(str!==null&&str!==undefined&&str!==0){ret=stringToUTF8OnStack(str)}return ret},array:arr=>{var ret=stackAlloc(arr.length);writeArrayToMemory(arr,ret);return ret}};function convertReturnValue(ret){if(returnType==="string"){return UTF8ToString(ret)}if(returnType==="boolean")return Boolean(ret);return ret}var func=getCFunc(ident);var cArgs=[];var stack=0;if(args){for(var i=0;i{var numericArgs=!argTypes||argTypes.every(type=>type==="number"||type==="boolean");var numericRet=returnType!=="string";if(numericRet&&numericArgs&&!opts){return getCFunc(ident)}return(...args)=>ccall(ident,returnType,argTypes,args,opts)};for(var base64ReverseLookup=new Uint8Array(123),i=25;i>=0;--i){base64ReverseLookup[48+i]=52+i;base64ReverseLookup[65+i]=i;base64ReverseLookup[97+i]=26+i}base64ReverseLookup[43]=62;base64ReverseLookup[47]=63;{if(Module["noExitRuntime"])noExitRuntime=Module["noExitRuntime"];if(Module["print"])out=Module["print"];if(Module["printErr"])err=Module["printErr"];if(Module["wasmBinary"])wasmBinary=Module["wasmBinary"];if(Module["arguments"])arguments_=Module["arguments"];if(Module["thisProgram"])thisProgram=Module["thisProgram"];if(Module["preInit"]){if(typeof Module["preInit"]=="function")Module["preInit"]=[Module["preInit"]];while(Module["preInit"].length>0){Module["preInit"].shift()()}}}Module["ccall"]=ccall;Module["cwrap"]=cwrap;Module["UTF8ToString"]=UTF8ToString;var _parseMarkdown,__emscripten_stack_restore,__emscripten_stack_alloc,_emscripten_stack_get_current,memory,__indirect_function_table,wasmMemory;function assignWasmExports(wasmExports){_parseMarkdown=Module["_parseMarkdown"]=wasmExports["parseMarkdown"];__emscripten_stack_restore=wasmExports["_emscripten_stack_restore"];__emscripten_stack_alloc=wasmExports["_emscripten_stack_alloc"];_emscripten_stack_get_current=wasmExports["emscripten_stack_get_current"];memory=wasmMemory=wasmExports["memory"];__indirect_function_table=wasmExports["__indirect_function_table"]}var wasmImports={__assert_fail:___assert_fail,__cxa_throw:___cxa_throw,_abort_js:__abort_js,emscripten_resize_heap:_emscripten_resize_heap};function run(){preRun();function doRun(){Module["calledRun"]=true;if(ABORT)return;initRuntime();readyPromiseResolve?.(Module);Module["onRuntimeInitialized"]?.();postRun()}if(Module["setStatus"]){Module["setStatus"]("Running...");setTimeout(()=>{setTimeout(()=>Module["setStatus"](""),1);doRun()},1)}else{doRun()}}var wasmExports;wasmExports=await (createWasm());run();if(runtimeInitialized){moduleRtn=Module}else{moduleRtn=new Promise((resolve,reject)=>{readyPromiseResolve=resolve;readyPromiseReject=reject})} -+;return moduleRtn}})();if(typeof exports==="object"&&typeof module==="object"){module.exports=createMd4cModule;module.exports.default=createMd4cModule}else if(typeof define==="function"&&define["amd"])define([],()=>createMd4cModule); ++var createMd4cModule = (() => { ++ var _scriptName = typeof document != 'undefined' ? document.currentScript?.src : undefined; ++ return ( ++async function(moduleArg = {}) { ++ var moduleRtn; ++ ++var Module=moduleArg;var ENVIRONMENT_IS_WEB=true;var ENVIRONMENT_IS_WORKER=false;var arguments_=[];var thisProgram="./this.program";var scriptDirectory="";var readAsync,readBinary;if(ENVIRONMENT_IS_WEB||ENVIRONMENT_IS_WORKER){try{scriptDirectory=new URL(".",_scriptName).href}catch{}{readAsync=async url=>{var response=await fetch(url,{credentials:"same-origin"});if(response.ok){return response.arrayBuffer()}throw new Error(response.status+" : "+response.url)}}}else{}var out=console.log.bind(console);var err=console.error.bind(console);var wasmBinary;var ABORT=false;var readyPromiseResolve,readyPromiseReject;var wasmMemory;var HEAP8,HEAPU8,HEAP16,HEAPU16,HEAP32,HEAPU32,HEAPF32,HEAPF64;var HEAP64,HEAPU64;var runtimeInitialized=false;function updateMemoryViews(){var b=wasmMemory.buffer;HEAP8=new Int8Array(b);HEAP16=new Int16Array(b);HEAPU8=new Uint8Array(b);HEAPU16=new Uint16Array(b);HEAP32=new Int32Array(b);HEAPU32=new Uint32Array(b);HEAPF32=new Float32Array(b);HEAPF64=new Float64Array(b);HEAP64=new BigInt64Array(b);HEAPU64=new BigUint64Array(b)}function preRun(){if(Module["preRun"]){if(typeof Module["preRun"]=="function")Module["preRun"]=[Module["preRun"]];while(Module["preRun"].length){addOnPreRun(Module["preRun"].shift())}}callRuntimeCallbacks(onPreRuns)}function initRuntime(){runtimeInitialized=true;wasmExports["__wasm_call_ctors"]()}function postRun(){if(Module["postRun"]){if(typeof Module["postRun"]=="function")Module["postRun"]=[Module["postRun"]];while(Module["postRun"].length){addOnPostRun(Module["postRun"].shift())}}callRuntimeCallbacks(onPostRuns)}var runDependencies=0;var dependenciesFulfilled=null;function addRunDependency(id){runDependencies++;Module["monitorRunDependencies"]?.(runDependencies)}function removeRunDependency(id){runDependencies--;Module["monitorRunDependencies"]?.(runDependencies);if(runDependencies==0){if(dependenciesFulfilled){var callback=dependenciesFulfilled;dependenciesFulfilled=null;callback()}}}function abort(what){Module["onAbort"]?.(what);what="Aborted("+what+")";err(what);ABORT=true;what+=". Build with -sASSERTIONS for more info.";var e=new WebAssembly.RuntimeError(what);readyPromiseReject?.(e);throw e}var wasmBinaryFile;function findWasmBinary(){return base64Decode("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8AFrIgMkAAJAAkAgAkUEQEEBIQkMAQsCQAJAAkACQAJAAkACQAJAAkACQAJAAkACQCAADhACAQAGBA0FBwgNAwkKCw0MDQtBPBB/IgBCADcCECAAQQM2AgwgAEGUFzYCACAAQgA3AgQgAEIANwI0IABCgICA/AM3AiwgAEIANwIYIABCADcCICAAQQA2AiggAEEMaiEGAkAgAUUNAAJAAkAgASgCBCIEBEAgASgCACIHDQELIANBADYC6AEgA0IANwPgAQwBCyAEQfj///8HTw0PAkAgBEELTwRAIARBB3IiCEEBahB/IQUgAyAIQf////8HazYC6AEgAyAFNgLgASADIAQ2AuQBDAELIAMgBDoA6wEgA0HgAWohBQsgBARAIAUgByAE/AoAAAsgBCAFakEAOgAAIAMoAuQBIAMtAOsBIgQgBMBBAEgbRQ0AIAZBkNwAIANB4AFqEBoLAkACQCABKAIUIgQEQCABKAIQIgUNAQsgA0EANgLYASADQgA3A9ABDAELIARB+P///wdPDQ8CQCAEQQtPBEAgBEEHciIHQQFqEH8hASADIAdB/////wdrNgLYASADIAE2AtABIAMgBDYC1AEMAQsgAyAEOgDbASADQdABaiEBCyAEBEAgASAFIAT8CgAACyABIARqQQA6AAAgAygC1AEgAy0A2wEiASABwEEASBtFDQAgBkGc3AAgA0HQAWoQGgsgAywA2wFBAEgEQCADKALYARogAygC0AEQcgsgAywA6wFBAE4NACADKALoARogAygC4AEQcgsgAyAANgLMASADIAY2AsgBIAAgACgCBEEBajYCBCADIAMpAsgBNwMAIAIgAxAYIAAgACgCBCICQQFrNgIEIAINDCAAIAAoAgAoAggRAQAgABB8DAwLQTwQfyIAQgA3AhAgAEEGNgIMIABBlBc2AgAgAEIANwIEIABCADcCNCAAQoCAgPwDNwIsIABCADcCGCAAQgA3AiAgAEEANgIoIAMgADYCxAEgAyAAQQxqNgLAASADIAMpAsABNwMIIAIgA0EIahAYDAsLQTwQfyIAQgA3AhAgAEEHNgIMIABBlBc2AgAgAEIANwIEIABCADcCNCAAQoCAgPwDNwIsIABCADcCGCAAQgA3AiAgAEEANgIoIAMgADYCvAEgAyAAQQxqNgK4ASADIAMpArgBNwMQIAIgA0EQahAYDAoLQTwQfyIAQgA3AhAgAEEJNgIMIABBlBc2AgAgAEIANwIEIABCADcCNCAAQoCAgPwDNwIsIABCADcCGCAAQgA3AiAgAEEANgIoIAMgADYCtAEgAyAAQQxqNgKwASADIAMpArABNwMYIAIgA0EYahAYDAkLQTwQfyIAQgA3AhAgAEEKNgIMIABBlBc2AgAgAEIANwIEIABCADcCNCAAQoCAgPwDNwIsIABCADcCGCAAQgA3AiAgAEEANgIoIAMgADYCrAEgAyAAQQxqNgKoASADIAMpAqgBNwMgIAIgA0EgahAYDAgLQTwQfyIAQgA3AhAgAEEINgIMIABBlBc2AgAgAEIANwIEIABCADcCNCAAQoCAgPwDNwIsIABCADcCGCAAQgA3AiAgAEEANgIoIAMgADYCpAEgAyAAQQxqNgKgASADIAMpAqABNwMoIAIgA0EoahAYDAcLQTwQfyIAQgA3AhAgAEELNgIMIABBlBc2AgAgAEIANwIEIABCADcCNCAAQoCAgPwDNwIsIABCADcCGCAAQgA3AiAgAEEANgIoIABBDGohBgJAIAFFDQACQAJAIAEoAgQiBARAIAEoAgAiBw0BCyADQQA2AugBIANCADcD4AEMAQsgBEH4////B08NCQJAIARBC08EQCAEQQdyIghBAWoQfyEFIAMgCEH/////B2s2AugBIAMgBTYC4AEgAyAENgLkAQwBCyADIAQ6AOsBIANB4AFqIQULIAQEQCAFIAcgBPwKAAALIAQgBWpBADoAACADKALkASADLQDrASIEIATAQQBIG0UNACAGQZDcACADQeABahAaCwJAAkAgASgCFCIEBEAgASgCECIFDQELIANBADYC2AEgA0IANwPQAQwBCyAEQfj///8HTw0JAkAgBEELTwRAIARBB3IiB0EBahB/IQEgAyAHQf////8HazYC2AEgAyABNgLQASADIAQ2AtQBDAELIAMgBDoA2wEgA0HQAWohAQsgBARAIAEgBSAE/AoAAAsgASAEakEAOgAAIAMoAtQBIAMtANsBIgEgAcBBAEgbRQ0AIAZBnNwAIANB0AFqEBoLIAMsANsBQQBIBEAgAygC2AEaIAMoAtABEHILIAMsAOsBQQBODQAgAygC6AEaIAMoAuABEHILIAMgADYCnAEgAyAGNgKYASAAIAAoAgRBAWo2AgQgAyADKQKYATcDMCACIANBMGoQGCAAIAAoAgQiAkEBazYCBCACDQYgACAAKAIAKAIIEQEAIAAQfAwGC0E8EH8iAEIANwIQIABBGDYCDCAAQZQXNgIAIABCADcCBCAAQgA3AjQgAEKAgID8AzcCLCAAQgA3AhggAEIANwIgIABBADYCKCADIAA2ApQBIAMgAEEMajYCkAEgAyADKQKQATcDOCACIANBOGoQGAwFC0E8EH8iAEIANwIQIABBGTYCDCAAQZQXNgIAIABCADcCBCAAQgA3AjQgAEKAgID8AzcCLCAAQgA3AhggAEIANwIgIABBADYCKCADIAA2AowBIAMgAEEMajYCiAEgAyADKQKIATcDQCACIANBQGsQGAwEC0E8EH8iAEIANwIQIABBGjYCDCAAQZQXNgIAIABCADcCBCAAQgA3AjQgAEKAgID8AzcCLCAAQgA3AhggAEIANwIgIABBADYCKCADIAA2AoQBIAMgAEEMajYCgAEgAyADKQKAATcDSCACIANByABqEBgMAwtBPBB/IgBCADcCECAAQRs2AgwgAEGUFzYCACAAQgA3AgQgAEIANwI0IABCgICA/AM3AiwgAEIANwIYIABCADcCICAAQQA2AiggAyAANgJ8IAMgAEEMajYCeCADIAMpAng3A1AgAiADQdAAahAYDAILQTwQfyIAQgA3AhAgAEEcNgIMIABBlBc2AgAgAEIANwIEIABCADcCNCAAQoCAgPwDNwIsIABCADcCGCAAQgA3AiAgAEEANgIoIAMgADYCdCADIABBDGo2AnAgAyADKQJwNwNYIAIgA0HYAGoQGAwBC0E8EH8iAEIANwIQIABBHTYCDCAAQZQXNgIAIABCADcCBCAAQgA3AjQgAEKAgID8AzcCLCAAQgA3AhggAEIANwIgIABBADYCKCADIAA2AmwgAyAAQQxqNgJoIAMgAykCaDcDYCACIANB4ABqEBgLIANB8AFqJAAgCQ8LEAcAC9cYAQp/IwBB4ABrIgMkAAJAIAJFBEBBASEADAELAkACQCAADgkCAQEBAQEBAQABC0EAIQAgAkEAOgAkIANCADcDGCADQgA3AxAgA0KAgICAgICAwD83AyAgA0IANwMIAkAgAigCLCACLAAzIgQgBEEASCIBGyIFRQ0AIAJBKGoiBigCACIHIAYgARshAQNAIAAgAWotAAAQUwRAIABBAWoiACAFRw0BDAILCyAHIAYgBEEASBsgAGotAABBPEcNAAJAIABBAWoiACAFTw0AIAcgBiAEQQBIGyIBIABqLQAAQS9GDQEDQCAAIAFqLQAAEFNFDQEgAEEBaiIAIAVHDQALDAELIAAgBU8NACAHIAYgBEEASBshByAAIQECQANAIAEgB2oiBC0AABBTDQEgBC0AAEE+Rg0BIAQtAABBL0YNASABQQFqIgEgBUcNAAsgBSEBCyAAIAFGDQAgA0EIaiABIABrEJgBIAAgAUkEQANAIANBCGogAigCKCAGIAIsADNBAEgbIABqLQAAEGLAEJ0BIABBAWoiACABRw0ACwsgASACKAIsIgggAiwAMyIJIAlBAEgbIgBPDQAgCUEfdiEFIANBFGohCiADQdAAaiELA0AgBigCACAGIAVBAXEbIQUDQCABIAVqIgQtAAAQUwRAIAFBAWoiASAASQ0BDAMLCyAELQAAQT5GDQEgBC0AAEEvRg0BAkACQCAAIAFLBEAgASEEAkADQCAEIAVqIgctAABBPUYNASAHLQAAEFMNASAHLQAAQT5GDQEgBy0AAEEvRg0BIARBAWoiBCAASQ0ACyAAIQQLIAEgBEcNAQsgAUEBaiEBDAELIAtBADYCACADQgA3A0ggA0HIAGogBCABaxCYASABIARJBEADQCADQcgAaiACKAIoIAYgAiwAM0EASBsgAWotAAAQYsAQnQEgAUEBaiIBIARJDQALCwJAAn8CQCAEIAIoAiwgAiwAMyIAIABBAEgiBRsiAE8NACAGKAIAIAYgBRshBQJAA0AgBCAFaiIBLQAAEFNFDQEgBEEBaiIEIABHDQALIAAMAgsgAS0AAEE9Rw0AAkACQAJAAkACQANAIAAgBCIHQQFqIgRNDQEgBCAFaiIBLQAAEFMNAAsgA0FAayIJQQA2AgAgA0IANwM4AkAgAS0AAEEiRg0AIAEtAABBJ0YNACAEIQEDQCABIAVqIgktAAAQUw0DIAktAABBPkYNAyAJLQAAQS9GDQMgAUEBaiIBIABHDQALIAAhAQwCCyAHQQJqIgchBAJAIAAgB00NACABLQAAIQEDQCAEIAVqLQAAIAFGDQEgBEEBaiIEIABJDQALIAAhBAsgACAHayIAIAQgB2siASAAIAFJGyIAQfj///8HTw0DAkACQCAAQQtPBEAgAEEHciIIQQFqEH8hASADIAhB/////wdrNgI0IAMgATYCLCADIAA2AjAMAQsgAyAAOgA3IANBLGohASAARQ0BCyAARQ0AIAEgBSAHaiAA/AoAAAsgACABakEAOgAAIAMsAENBAEgEQCADKAJAGiADKAI4EHILIAkgAygCNDYCACADIAMpAiw3AzggBCAEIAIoAiwgAiwAMyIAIABBAEgbSWohAQwCCyADQUBrQQA2AgAgA0IANwM4IAQhAQsgACAHTQ0CIAAgBGsiACABIARrIgcgACAHSRsiAEH4////B08NAQJAAkAgAEELTwRAIABBB3IiCUEBahB/IQcgAyAJQf////8HazYCNCADIAc2AiwgAyAANgIwDAELIAMgADoANyADQSxqIQcgAEUNAQsgAEUNACAHIAQgBWogAPwKAAALIAAgB2pBADoAACADLABDQQBIBEAgAygCQBogAygCOBByCyADQUBrIAMoAjQ2AgAgAyADKQIsNwM4CyADIANByABqNgJcIANBLGogCiADQcgAaiADQdwAahAZAkAgAygCLCIFQRRqIgAgA0E4akYNACADLABDIQQgBSwAH0EATgRAIARBAE4EQCAAIAMpAzg3AgAgACADQUBrKAIANgIIDAcLIAAgAygCOCADKAI8EJwBDAELIAAgAygCOCADQThqIARBAEgiBRsgAygCPCAEIAUbEJsBCyADLABDQQBODQQgAygCQBogAygCOBByDAQLEAcAC0EIEKgBQfIOEIEBIgBBrNsANgIAIABBuNsAQQEQAAALIAQLIQEgAyADQcgAajYCLCADQThqIAogA0HIAGogA0EsahAZAn8gAygCOCIALAAfQQBIBEAgAEEANgIYIAAoAhQMAQsgAEEAOgAfIABBFGoLQQA6AAALIAMsAFNBAEgEQCADKAJQGiADKAJIEHILIAIoAiwhCCACLQAzIQkLIAEgCCAJQf8BcSAJwEEASCIFGyIASQ0ACwtBACEAQQAhBQJAIAMoAgwgAywAEyIBIAFBAEgbQQVHDQAgAygCCCADQQhqIAFBAEgbQcAMQQUQVQ0AIANBAzoAUyADQQA6AEsgA0HnEC8AADsBSCADQekQLQAAOgBKAn8gA0EUaiEKQQAhCSADQcgAaiIGKAIEIAYsAAsiCCAIQQBIIgQbIgchCCAGKAIAIAYgBBsi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+AEgA0H4AWogBUEASCIEGyADKAL8ASAFIAQbEJsBCyADLACDAkEATg0AIAMoAoACGiADKAL4ARByCyADIAA2AvQBIAMgAEEMajYC8AEgACAAKAIEQQFqNgIEIAMgAykC8AE3AwggAiADQQhqEBggACAAKAIEIgJBAWs2AgQgAg0OIAAgACgCACgCCBEBACAAEHwMDgtBPBB/IgBCADcCECAAQQw2AgwgAEGUFzYCACAAQgA3AgQgAEIANwI0IABCgICA/AM3AiwgAEIANwIYIABCADcCICAAQQA2AiggAyAANgLsASADIABBDGo2AugBIAMgAykC6AE3AxAgAiADQRBqEBgMDQtBPBB/IgBCADcCECAAQSA2AgwgAEGUFzYCACAAQgA3AgQgAEIANwI0IABCgICA/AM3AiwgAEIANwIYIABCADcCICAAQQA2AiggAEEMaiEEAkAgAUUNAAJAAkAgASgCBCIFBEAgASgCACIGDQELIANBADYCgAIgA0IANwP4AQwBCyAFQfj///8HTw0PAkAgBUELTwRAIAVBB3IiB0EBahB/IQEgAyAHQf////8HazYCgAIgAyABNgL4ASADIAU2AvwBDAELIAMgBToAgwIgA0H4AWohAQsgBQRAIAEgBiAF/AoAAAsgASAFakEAOgAAIAMoAvwBIAMtAIMCIgEgAcBBAEgbRQ0AIARB9NwAIANB+AFqEBoLIAMsAIMCQQBODQAgAygCgAIaIAMoAvgBEHILIAMgADYC5AEgAyAENgLgASAAIAAoAgRBAWo2AgQgAyADKQLgATcDGCACIANBGGoQGCAAIAAoAgQiAkEBazYCBCACDQwgACAAKAIAKAIIEQEAIAAQfAwMC0E8EH8iAEIANwIQIABBDTYCDCAAQZQXNgIAIABCADcCBCAAQgA3AjQgAEKAgID8AzcCLCAAQgA3AhggAEIANwIgIABBADYCKCADIAA2AtwBIAMgAEEMajYC2AEgAyADKQLYATcDICACIANBIGoQGAwLC0E8EH8iAEIANwIQIABBDjYCDCAAQZQXNgIAIABCADcCBCAAQgA3AjQgAEKAgID8AzcCLCAAQgA3AhggAEIANwIgIABBADYCKCAAQQxqIQQCQCABRQ0AIAEoAgAiAUEBRg0AIANB+AFqIAEQnwEgBEHc3AAgA0H4AWoQGiADLACDAkEATg0AIAMoAoACGiADKAL4ARByCyADIAA2AtQBIAMgBDYC0AEgACAAKAIEQQFqNgIEIAMgAykC0AE3AyggAiADQShqEBggACAAKAIEIgJBAWs2AgQgAg0KIAAgACgCACgCCBEBACAAEHwMCgtBPBB/IgBCADcCECAAQQ82AgwgAEGUFzYCACAAQgA3AgQgAEIANwI0IABCgICA/AM3AiwgAEIANwIYIABCADcCICAAQQA2AiggAEEMaiEEAkAgAUUNACABKAIARQ0AIARBxNwAIANB+AFqQacPEBsiBRAaIAUsAAtBAEgEQCAFKAIIGiAFKAIAEHILIARB0NwAIANB+AFqQacPQccPIAEtAARB3wFxQdgARhsQGyIBEBogASwAC0EATg0AIAEoAggaIAEoAgAQcgsgAyAANgLMASADIAQ2AsgBIAAgACgCBEEBajYCBCADIAMpAsgBNwMwIAIgA0EwahAYIAAgACgCBCICQQFrNgIEIAINCSAAIAAoAgAoAggRAQAgABB8DAkLQTwQfyIAQgA3AhAgAEEQNgIMIABBlBc2AgAgAEIANwIEIABCADcCNCAAQoCAgPwDNwIsIABCADcCGCAAQgA3AiAgAEEANgIoIABBDGohBAJAIAFFDQACQCABLQAgIgVFDQAgA0EAOgClASADIAU6AKQBIARBqNwAIANB+AFqIANBpAFqEBsiBRAaIAUsAAtBAE4NACAFKAIIGiAFKAIAEHILAkACQCABKAIUIgUEQCABKAIQIgYNAQsgA0EANgKAAiADQgA3A/gBDAELIAVB+P///wdPDQsCQCAFQQtPBEAgBUEHciIHQQFqEH8hASADIAdB/////wdrNgKAAiADIAE2AvgBIAMgBTYC/AEMAQsgAyAFOgCDAiADQfgBaiEBCyAFBEAgASAGIAX8CgAACyABIAVqQQA6AAAgAygC/AEgAy0AgwIiASABwEEASBtFDQAgBEG43AAgA0H4AWoQGgsgAywAgwJBAE4NACADKAKAAhogAygC+AEQcgsgAyAANgLEASADIAQ2AsABIAAgACgCBEEBajYCBCADIAMpAsABNwM4IAIgA0E4ahAYIAAgACgCBCICQQFrNgIEIAINCCAAIAAoAgAoAggRAQAgABB8DAgLQTwQfyIAQgA3AhAgAEERNgIMIABBlBc2AgAgAEIANwIEIABCADcCNCAAQoCAgPwDNwIsIABCADcCGCAAQgA3AiAgAEEANgIoIAMgADYCvAEgAyAAQQxqNgK4ASADIAMpArgBNwNAIAIgA0FAaxAYDAcLQTwQfyIAQgA3AhAgAEEfNgIMIABBlBc2AgAgAEIANwIEIABCADcCNCAAQoCAgPwDNwIsIABCADcCGCAAQgA3AiAgAEEANgIoIABBDGohBAJAIAFFDQAgA0H4AWogASgCABCfASADQejcADYCmAIgA0GkAWogAEEcakHo3AAgA0GYAmoQGQJAIAMoAqQBIgVBFGoiASADQfgBakYNACADLACDAiEGIAUsAB9BAE4EQCAGQQBOBEAgASADKQL4ATcCACABIAMoAoACNgIIDAILIAEgAygC+AEgAygC/AEQnAEMAQsgASADKAL4ASADQfgBaiAGQQBIIgUbIAMoAvwBIAYgBRsQmwELIAMsAIMCQQBODQAgAygCgAIaIAMoAvgBEHILIAMgADYCtAEgAyAENgKwASAAIAAoAgRBAWo2AgQgAyADKQKwATcDSCACIANByABqEBggACAAKAIEIgJBAWs2AgQgAg0GIAAgACgCACgCCBEBACAAEHwMBgtBPBB/IgBCADcCECAAQRI2AgwgAEGUFzYCACAAQgA3AgQgAEIANwI0IABCgICA/AM3AiwgAEIANwIYIABCADcCICAAQQA2AiggAEEMaiEFAkAgAUUNACADQQA6AIACIANC496xm/Stnbf0ADcD+AEgA0EIOgCDAiADQaQBaiABKAIAEJ8BIAMgA0H4AWo2ApQCIANBmAJqIABBHGoiBiADQfgBaiADQZQCahAZAkAgAygCmAIiB0EUaiIEIANBpAFqRg0AIAMsAK8BIQggBywAH0EATgRAIAhBAE4EQCAEIAMpAqQBNwIAIAQgAygCrAE2AggMAgsgBCADKAKkASADKAKoARCcAQwBCyAEIAMoAqQBIANBpAFqIAhBAEgiBxsgAygCqAEgCCAHGxCbAQsgAywArwFBAEgEQCADKAKsARogAygCpAEQcgsgAywAgwJBAEgEQCADKAKAAhogAygC+AEQcgsgA0EQEH8iBDYC+AEgA0KMgICAgIKAgIB/NwL8ASAEQf0JKAAANgAIIARB9QkpAAA3AAAgBEEAOgAMIANBpAFqIAEoAgQQnwEgAyADQfgBajYClAIgA0GYAmogBiADQfgBaiADQZQCahAZAkAgAygCmAIiB0EUaiIEIANBpAFqRg0AIAMsAK8BIQggBywAH0EATgRAIAhBAE4EQCAEIAMpAqQBNwIAIAQgAygCrAE2AggMAgsgBCADKAKkASADKAKoARCcAQwBCyAEIAMoAqQBIANBpAFqIAhBAEgiBxsgAygCqAEgCCAHGxCbAQsgAywArwFBAEgEQCADKAKsARogAygCpAEQcgsgAywAgwJBAEgEQCADKAKAAhogAygC+AEQcgsgA0EQEH8iBDYC+AEgA0KMgICAgIKAgIB/NwL8ASAEQfAJKAAANgAIIARB6AkpAAA3AAAgBEEAOgAMIANBpAFqIAEoAggQnwEgAyADQfgBajYClAIgA0GYAmogBiADQfgBaiADQZQCahAZAkAgAygCmAIiBEEUaiIBIANBpAFqRg0AIAMsAK8BIQYgBCwAH0EATgRAIAZBAE4EQCABIAMpAqQBNwIAIAEgAygCrAE2AggMAgsgASADKAKkASADKAKoARCcAQwBCyABIAMoAqQBIANBpAFqIAZBAEgiBBsgAygCqAEgBiAEGxCbAQsgAywArwFBAEgEQCADKAKsARogAygCpAEQcgsgAywAgwJBAE4NACADKAKAAhogAygC+AEQcgsgAyAANgKgASADIAU2ApwBIAAgACgCBEEBajYCBCADIAMpApwBNwNQIAIgA0HQAGoQGCAAIAAoAgQiAkEBazYCBCACDQUgACAAKAIAKAIIEQEAIAAQfAwFC0E8EH8iAEIANwIQIABBEzYCDCAAQZQXNgIAIABCADcCBCAAQgA3AjQgAEKAgID8AzcCLCAAQgA3AhggAEIANwIgIABBADYCKCADIAA2ApgBIAMgAEEMajYClAEgAyADKQKUATcDWCACIANB2ABqEBgMBAtBPBB/IgBCADcCECAAQRQ2AgwgAEGUFzYCACAAQgA3AgQgAEIANwI0IABCgICA/AM3AiwgAEIANwIYIABCADcCICAAQQA2AiggAyAANgKQASADIABBDGo2AowBIAMgAykCjAE3A2AgAiADQeAAahAYDAMLQTwQfyIAQgA3AhAgAEEVNgIMIABBlBc2AgAgAEIANwIEIABCADcCNCAAQoCAgPwDNwIsIABCADcCGCAAQgA3AiAgAEEANgIoIAMgADYCiAEgAyAA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IQwDQCAGIApBA3QiDWooAgAiASgCACIJQQ1rQQJPBH8gCkEBagVBASEIAkAgASgCJCIFIAEoAigiBEYNACAFIQEDQAJAAkAgASgCACICKAIAQQ9HDQAgAigCKCACKAIkIgJrQQhHDQAgAigCACgCAEEhRg0BCyABQQhqIgEgBEcNAQwCCwsgA0EANgIcIANCADcCFCADQQA2AhAgA0IANwIIA0ACQAJAIAUoAgAiASgCAEEPRw0AIAEoAiggASgCJCIBa0EIRw0AIAEoAgAoAgBBIUcNACADKAIIIgIgAygCDCIGRwRAQTwQfyIBQgA3AhAgASAJNgIMIAFBlBc2AgAgAUIANwIEIAFCADcCGCABQgA3AiAgAUKAgICAgICAwD83AiggAyABNgIEIAMgAUEMajYCACABIANBEGoiBygCADYCOCABIAY2AjQgASACNgIwIAdBADYCACADQgA3AwggA0EUaiADEB0CQCADKAIEIgFFDQAgASABKAIEIgJBAWs2AgQgAg0AIAEgASgCACgCCBEBACABEHwLIAUoAgAoAiQhAQsgAygCGCICIAMoAhwiB0kEQCACIAEoAgA2AgAgAiABKAIEIgE2AgQgAQRAIAEgASgCBEEBajYCBAsgAyACQQhqNgIYDAILIAIgAygCFCIGayICQQN1Ig5BAWoiCEGAgICAAk8NB0H/////ASAHIAZrIgdBAnUiCyAIIAggC0kbIAdB+P///wdPGyIIQYCAgIACTw0IIAhBA3QiBxB/IgsgAmoiCCABKAIANgIAIAggASgCBCIBNgIEIAcgC2ohByAIIAEEfyABIAEoAgRBAWo2AgQgAygCHBogAygCGCAGayICQQN1BSAOC0EDdGshASACBEAgASAGIAL8CgAACyADIAc2AhwgAyAIQQhqIgI2AhggAyABNgIUIAYEQCAGEHILIAMgAjYCGAwBCyADQQhqIAUQHQsgBUEIaiIFIARHDQALAkAgAygCCCICIAMoAgwiBEYNAEE8EH8iAUIANwIQIAEgCTYCDCABQZQXNgIAIAFCADcCBCABQgA3AhggAUIANwIgIAFCgICAgICAgMA/NwIoIAMgATYCBCADIAFBDGo2AgAgASADKAIQNgI4IAEgBDYCNCABIAI2AjAgA0EANgIQIANCADcDCCADQRRqIAMQHSADKAIEIgFFDQAg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ASwAH0EASARAIAEoAhwaIAEoAhQQcgsgASwAE0EASARAIAEoAhAaIAEoAggQcgsgARByIAIiAQ0ACwsgACgCACEBIABBADYCACABBEAgACgCBBogARByCwuNAgEGfyAAKAIEIgIgACgCCCIDSQRAIAIgASgCADYCACACIAEoAgQ2AgQgAUIANwIAIAAgAkEIajYCBA8LAkAgAiAAKAIAIgRrIgVBA3UiB0EBaiICQYCAgIACSQRAQf////8BIAMgBGsiBkECdSIDIAIgAiADSRsgBkH4////B08bIgMEfyADQYCAgIACTw0CIANBA3QQfwVBAAsiBiAFaiICIAEoAgA2AgAgAiABKAIENgIEIAFCADcCACACIAdBA3RrIQEgBQRAIAEgBCAF/AoAAAsgACAGIANBA3RqNgIIIAAgAkEIaiICNgIEIAAgATYCACAEBEAgBBByCyAAIAI2AgQPCxATAAsQFAALzgEBA38jAEEQayICJAAgABAQAkAgASgCACIDRQ0AIAAoAgggACgCDCIARg0AIABBCGsoAgAhBCABKAIEIgAEQCAAIAAoAgRBAWo2AgQLIAIgADYCDCACIAM2AgggBEEkaiACQQhqEB0gAigCDCIARQ0AIAAgACgCBCIDQQFrNgIEIAMNACAAIAAoAgAoAggRAQAgABB8CwJAIAEoAgQiAUUNACABIAEoAgQiAEEBazYCBCAADQAgASABKAIAKAIIEQEAIAEQfAsgAkEQaiQAC90FAQd/IwBBMGsiASQAIAAoAgAiAygCACIEIAMoAgQiAkcEQCAEIQMCQAJAA0AgAygCABARBEAgAiADQQhqIgNHDQEMAgsLQTwQfyICQgA3AhAgAkEBNgIMIAJBlBc2AgAgAkIANwIEIAJCADcCNCACQoCAgPwDNwIsIAJCADcCGCACQgA3AiAgAkEANgIoIAEgAjYCHCABIAJBDGo2AhggAUGqCi0AADoAECABQQU6ABcgAUGmCigAADYCDCABQQA6ABEgAUEAOgAEIAFB9OTVqwY2AgAgAUEEOgALIAEgAUEMajYCJCABQShqIAJBHGogAUEMaiABQSRqEBkCQCABKAIoIgNBFGoiBCABRg0AIAMsAB9BAE4EQCAEIAEpAgA3AgAgBCABKAIINgIIDAELIAQgAUEEEJsBIAEsAAtBAE4NACABKAIIGiABKAIAEHILIAEsABdBAEgEQCABKAIUGiABKAIMEHILIAAoAgAhBSACKAIwIgcEQCAHIgMgAigCNCIERwRAA0ACQCAEQQRrKAIAIgNFDQAgAyADKAIEIgZBAWs2AgQgBg0AIAMgAygCACgCCBEBACADEHwLIAcgBEEIayIERw0ACyACKAIwIQMLIAIgBzYCNCACKAI4GiADEHIgAkEANgI4IAJCADcCMAsgAiAFKAIANgIwIAIgBSgCBDYCNCACIAUoAgg2AjggBUEANgIIIAVCADcCACAAKAIEIAFBGGoQHSABKAIcIgRFDQEgBCAEKAIEIgNBAWs2AgQgAw0BIAQgBCgCACgCCBEBACAEEHwMAQsDQCAAKAIEIAQQHSAEQQhqIgQgAkcNAAsLIAAoAgAiBigCACIAIAYoAgQiBEcEQANAAkAgBEEEaygCACIDRQ0AIAMgAygCBCICQQFrNgIEIAINACADIAMoAgAoAggRAQAgAxB8CyAAIARBCGsiBEcNAAsLIAYgADYCBAsgAUEwaiQACyAAQY/cACwAAEEASARAQYzcACgCABpBhNwAKAIAEHILCyAAQZvcACwAAEEASARAQZjcACgCABpBkNwAKAIAEHILCyAAQafcACwAAEEASARAQaTcACgCABpBnNwAKAIAEHILCyAAQbPcACwAAEEASARAQbDcACgCABpBqNwAKAIAEHILCyAAQcPcACwAAEEASARAQcDcACgCABpBuNwAKAIAEHILCyAAQc/cACwAAEEASARAQczcACgCABpBxNwAKAIAEHILCyAAQdvcACwAAEEASARAQdjcACgCABpB0NwAKAIAEHILCyAAQefcACwAAEEASARAQeTcACgCABpB3NwAKAIAEHILCyAAQfPcACwAAEEASARAQfDcACgCABpB6NwAKAIAEHILCyAAQf/cACwAAEEASARAQfzcACgCABpB9NwAKAIAEHILCwwAIABBlBc2AgAgAAsOACAAQZQXNgIAIAAQcgusAQEFfyMAQRBrIgQkACAAQQxqIgEoAiQiAgRAIAIiACABKAIoIgNHBEADQAJAIANBBGsoAgAiAEUNACAAIAAoAgQiBUEBazYCBCAFDQAgACAAKAIAKAIIEQEAIAAQfAsgAiADQQhrIgNHDQALIAEoAiQhAAsgASACNgIoIAEoAiwaIAAQcgsgAUEQ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ACABGyEADAELCyADQRBqJAAgBUEQaiQAIAALBQAQdgALDQAgACgCACABKAIASQsEACAACyoBAX8CQCAAQQhqIgEoAgAEQCABEH1Bf0cNAQsgACAAKAIAKAIQEQEACwsTACAAIAAoAgBBAWsiADYCACAACwQAQQALPQECf0EBIAAgAEEBTRshAQNAAkAgARBxIgINAEGw4gAoAgAiAEUNACAAEQkADAELCyACIgBFBEAQeQsgAAsNACAAQdjZADYCACAAC10BA38gABCAASIAQcjaADYCACAAQQRqIQQgARBhIgNBDWoQfyICQQA2AgggAiADNgIEIAIgAzYCACACQQxqIQIgA0EBaiIDBEAgAiABIAP8CgAACyAEIAI2AgAgAAsKACAALQALQQd2CxUAIAAQggEEQCAAKAIEDwsgABCHAQsbAQF/QQohASAAEIIBBH8gABCIAUEBawUgAQsLEgAgABCCAQRAIAAoAgAPCyAAC6gCAQN/IwBBIGsiCCQAQff///8HIgkgAUF/c2ogAk8EQCAAEIUBIQogAUHz////A0kEQCAIIAFBAXQ2AhwgCCABIAJqNgIQIAhBEGogCEEcahCMASgCABCNAUEBaiEJCyAIQRxqIAhBGGogABCOASgCABCPASAIQRBqIAkQkAEgCCgCECEJIAgoAhQaIAQEQCAJIAogBBCRAQsgBgRAIAQgCWogByAGEJEBCyADIAQgBWoiB2shAiADIAdHBEAgBCAJaiAGaiAEIApqIAVqIAIQkQELIAFBCkcEQCAKEHILIAAgCRCSASAAIAgoAhQQkwEgACAEIAZqIAJqIgQQlAEgCEEAOgAPIAQgCWogCEEPahCLASAIQRxqEJoBIAhBIGokAA8LEJUBAAsLACAALQALQf8AcQsOACAAKAIIQf////8HcQsZAAJAIAJFDQAgAkUNACAAIAEgAvwKAAALCxkAIAAQggEEQCAAIAEQlAEPCyAAIAEQlwELDAAgACABLQAAOgAACyMBAn8jAEEQayICJAAgACABEHohAyACQRBqJAAgASAAIAMbCyQAIABBC08EfyAAQQhqQXhxIgAgAEEBayIAIABBC0YbBUEKCwsLACAAIAE2AgAgAAsKACAAIAEQjgEaCxgBAX8gARB/IQIgACABNgIEIAAgAjYCAAsLACAAIAEgAhCJAQsJACAAIAE2AgALEAAgACABQYCAgIB4cjYCCAsJACAAIAE2AgQLBQAQeQALBwAgAEELSQsNACAAIAFB/wBxOgALC64CAQZ/IAFB9////wdNBEAgABCEASABSQRAIAEQjQEhAiMAQRBrIgEkACABQQxqIAFBCGogABCOASgCABCPASAAEIQBIQQgABCDASEGAkACfyACEJYBIgcEQEEBIQQgAkEBaiEFIAAhAiAAKAIADAELIAJBAWohAwJAIAIgBEsEQCABIAMQkAEgASgCBCEFIAEoAgAhAgwBCyABIAMQkAEgASgCBCEDIAAQhAEhBCABKAIEIQUgASgCACECIANBAWsgBE0NACACEHIMAgsgABCCASEEIAAQhQELIQMgAiADIAAQgwFBAWoQkQEgBARAIAMQcgsgB0UEQCAAIAUQkwEgACAGEJQBIAAgAhCSAQwBCyAAIAYQlwELIAFBDGoQmgEgAUEQaiQACw8LEJUBAAt9AQN/IwBBEGsiBSQAAkAgAiAAEIQBIgQgABCDASIDa00EQCACRQ0BIAAQhQEiBCADaiABIAIQkQEgACACIANqIgIQigEgBUEAOgAPIAIgBGogBUEPahCLAQwBCyAAIAQgAiAEayADaiADIANBACACIAEQhgELIAVBEGokAAsLACAAKAIAEIMBGgt2AQN/IwBBEGsiBCQAIAAQiAEhAyAAKAIEIQUCQCACIANJBEAgACgCACEDIAAgAhCUASADIAEgAhCRASAEQQA6AA8gAiADaiAEQQ9qEIsBDAELIAAgA0EBayACIANrQQFqIAVBACAFIAIgARCGAQsgBEEQaiQAC2IBAn8jAEEQayIDJAAgABCHASEEAkAgAkEKTQRAIAAgAhCXASAAIAEgAhCRASADQQA6AA8gACACaiADQQ9qEIsBDAELIABBCiACQQprIARBACAEIAIgARCGAQsgA0EQaiQAC4IDAQZ/IwBBEGsiBCQAIAQgAToADwJAAkACfyAAEIIBIgNFBEBBCiECIAAQhwEMAQsgABCIAUEBayECIAAoAgQLIgEgAkYEQCMAQRBrIgUkACAFQQxqIAVBCGogABCOASgCABCPASMAQRBrIgMkAAJAIAJB9////wdHBEAgABCFASEGIANBBGogAkHz////A0kEfyADIAJBAXQ2AgwgAyACQQFqNgIEIANBBGogA0EMahCMASgCABCNAUEBagVB9////wcLEJABIAMoAgQhByADKAIIGiACBEAgByAGIAIQkQELIAJBCkcEQCAGEHILIAAgBxCSASAAIAMoAggQkwEgA0EQaiQADAELEJUBAAsgACACEJQBIAVBDGoQmgEgBUEQaiQAIAAQhQEaDAELIAAQhQEaIAMNACAAIgIgAUEBahCXAQwBCyAAKAIAIQIgACABQQFqEJQBCyABIAJqIgAgBEEPahCLASAEQQA6AA4gAEEBaiAEQQ5qEIsBIARBEGokAAsNACAAIAEgARBhEJkBC6wEAQZ/IwBBIGsiBCQAIARBDGoiBQJ/IARBIGoiAyAEQRVqIgJrIgZBCUwEQEE9IAZBICABQQFyZ2tB0QlsQQx1IgcgASAHQQJ0QfDUAGooAgBPakgNARoLAn8gAUG/hD1NBEAgAUGPzgBNBEAgAUHjAE0EQCABQQlNBEAgAiABEKABDAQLIAIgARChAQwDCyABQecHTQRAIAIgAUHkAG4iAhCgASABIAJB5ABsaxChAQwDCyACIAEQogEMAgsgAUGfjQZNBEAgAiABQZDOAG4iAhCgASABIAJBkM4AbGsQogEMAgsgAiABEKMBDAELIAFB/8HXL00EQCABQf+s4gRNBEAgAiABQcCEPW4iAhCgASABIAJBwIQ9bGsQowEMAgsgAiABEKQBDAELIAFB/5Pr3ANNBEAgAiABQYDC1y9uIgIQoAEgASACQYDC1y9saxCkAQwBCyACIAFBgMLXL24iAhChASABIAJBgMLXL2xrEKQBCyEDQQALNgIEIAUgAzYCACAEKAIMIQYjAEEQayICJAACQCAGIARBFWoiA2siBUH3////B00EQAJAIAUQlgEEQCAAIAUQlwEgACEBDAELIAJBCGogBRCNAUEBahCQASACKAIMGiAAIAIoAggiARCSASAAIAIoAgwQkwEgACAFEJQBCyABIAMgBiADayIDEJEBIAJBADoAByABIANqIAJBB2oQiwEgAkEQaiQADAELEJUBAAsgBEEgaiQACxEAIAAgAUEwajoAACAAQQFqC+sBAQV/IwBBEGsiBCQAIwBBIGsiAiQAIwBBEGsiAyQAIAMgAUEBdEGg1QBqIgEiBjYCDCADIAFBAmo2AgggAkEYaiADQQxqIANBCGoQpwEgA0EQaiQAIAIoAhghBSACKAIcIQMjAEEQayIBJAAgASADNgIMIAAgBSADIAVrIgMQiQEgASAAIANqNgIIIAJBEGogAUEMaiABQQhqEKYBIAFBEGokACACIAYgAigCEBClATYCDCACIAAgAigCFBClATYCCCAEQQhqIAJBDGogAkEIahCmASACQSBqJAAgBCgCDCEAIARBEGokACAACxsAIAAgAUHkAG4iABChASABIABB5ABsaxChAQsdACAAIAFBkM4AbiIAEKEBIAEgAEGQzgBsaxCiAQsdACAAIAFBwIQ9biIAEKEBIAEgAEHAhD1saxCjAQsKACAAIAEgAGtqCwsAIAAgASACEKcBCxYAIAAgASgCADYCACAAIAIoAgA2AgQLDgAgAEHQAGoQcUHQAGoLdAEBfyACRQRAIAAoAgQgASgCBEYPCyAAIAFGBEBBAQ8LIAEoAgQiAi0AACEBAkAgACgCBCIDLQAAIgBFDQAgACABRw0AA0AgAi0AASEBIAMtAAEiAEUNASACQQFqIQIgA0EBaiEDIAAgAUYNAAsLIAAgAUYLtQUBBn8jAEHQAGsiBCQAAkACf0EBIAAgAUEAEKkBDQAaQQAgAUUNABojAEEQayIFJAAgBUEEaiIDIAEoAgAiBkEIaygCACIHNgIIIAMgASAHajYCACADIAZBBGsoAgA2AgQgBSgCCCIGQZjXAEEAEKkBIQMgBSgCBCEHAkAgAwRAIAUoAgwhASMAQUBqIgMkACADQUBrJABBACAHIAEbIQMMAQsjAEFAaiIDJAAgASAHTgRAIANBHGoiCEIANwIAIANCADcCJCADQgA3AiwgA0IANwIUIANBADYCECADQZjXADYCDCADIAY2AgQgA0EANgI8IANCgYCAgICAgIABNwI0IAMgATYCCCAGIANBBGogByAHQQFBACAGKAIAKAIUEQoAIAFBACAIKAIAGyEICyADQUBrJAAgCCIDDQAjAEFAaiIDJAAgA0EANgIQIANB6NYANgIMIAMgATYCCCADQZjXADYCBEEAIQEgA0EUakEAQSf8CwAgA0EANgI8IANBAToAOyAGIANBBGogB0EBQQAgBigCACgCGBEIAAJAAkACQCADKAIoDgIAAQILIAMoAhhBACADKAIkQQFGG0EAIAMoAiBBAUYbQQAgAygCLEEBRhshAQwBCyADKAIcQQFHBEAgAygCLA0BIAMoAiBBAUcNASAD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dW50AGJhc2Vmb250AERvY3VtZW50AGltcG9ydGFudABkZWZhdWx0AHRpZ2h0AHJpZ2h0AEhpZ2hsaWdodABsZWZ0AGZyYW1lc2V0AGZpZWxkc2V0AGR0AFx0AGFkZHJlc3MAaHR0cHMAZGV0YWlscwBFbXBoYXNpcwBub2ZyYW1lcwAlczolZDogJXMAdHIAdmVjdG9yAGRpcgBocgBmb290ZXIAY2VudGVyAFNwb2lsZXIAaGVhZGVyAGZlbmNlQ2hhcgBccgBvcHRncm91cABjb2xncm91cABmdHAAL3NyYy9jcHAvd2FzbS9BU1RTZXJpYWxpemVyLmNwcAAvZW1zZGsvZW1zY3JpcHRlbi9zeXN0ZW0vbGliL2xpYmN4eGFiaS9zcmMvcHJpdmF0ZV90eXBlaW5mby5jcHAAdGlwAHZpZGVvAFZpZGVvAGNhdXRpb24Ab3B0aW9uAHN0ZDo6ZXhjZXB0aW9uAGZpZ2NhcHRpb24AQWRtb25pdGlvbgBzZWN0aW9uAG1haW4AYWxpZ24AbmFuAFxuAGZvcm0AbWVudWl0ZW0ATGlzdEl0ZW0AcGFyYW0AdWwAdXJsAGNvbABodG1sAFRhYmxlSGVhZGVyQ2VsbABUYWJsZUNlbGwAbGV2ZWwAZGwAaXNUYXNrAGxpbmsATGluawBDb2RlQmxvY2sAdHJhY2sAU29mdEJyZWFrAExpbmVCcmVhawBUaGVtYXRpY0JyZWFrAGxpAGJhZF9hcnJheV9uZXdfbGVuZ3RoAFBhcmFncmFwaABTdHJpa2V0aHJvdWdoAHNlYXJjaABkaWFsb2cAU3Ryb25nAGJhc2ljX3N0cmluZwBub2RlVHlwZVRvU3RyaW5nAHdhcm5pbmcASGVhZGluZwBpbmYAXGYAdHJ1ZQBibG9ja3F1b3RlAEJsb2NrcXVvdGUAbm90ZQBmYWxzZQBiYXNlAGZpZ3VyZQBhZG1vbml0aW9uVHlwZQBVbmRlcmxpbmUATGF0ZXhNYXRoSW5saW5lAEJsYW5rTGluZQBpZnJhbWUAdGl0bGUAYXJ0aWNsZQB0YWJsZQBUYWJsZQBJbWFnZQBDb2RlAGFzaWRlAHRkAGxlZ2VuZAB0YXNrQ2hlY2tlZABkZAB0aGVhZABUYWJsZUhlYWQAc3JjAHN0ZDo6YmFkX2FsbG9jAFxiACInPTw+YAAtXwAuLStfAFxcACh7WwAsImNoaWxkcmVuIjpbAE5BTgBJTkYAY2F0Y2hpbmcgYSBjbGFzcyB3aXRob3V0IGFuIG9iamVjdD8AXV0+AC0tPgBtYWlsdG86ACl9XS4hPyw7OgAsImNvbnRlbnQiOgBoNgBoNQBoNABoMwBoMgBoMQBodHRwOi8vAFRvbyBtYW55IGxpbmsgcmVmZXJlbmNlIGRlZmluaXRpb24gaW5zdGFudGlhdGlvbnMuAFVuc3VwcG9ydGVkIGFiaV92ZXJzaW9uLgBBYm9ydGVkIGZyb20gdGV4dCgpIGNhbGxiYWNrLgBBYm9ydGVkIGZyb20gZW50ZXJfc3BhbigpIGNhbGxiYWNrLgBBYm9ydGVkIGZyb20gbGVhdmVfc3BhbigpIGNhbGxiYWNrLgBBYm9ydGVkIGZyb20gZW50ZXJfYmxvY2soKSBjYWxsYmFjay4AQWJvcnRlZCBmcm9tIGxlYXZlX2Jsb2NrKCkgY2FsbGJhY2suAG1hbGxvYygpIGZhaWxlZC4AcmVhbGxvYygpIGZhaWxlZC4AQDouAC4hIyQlJicqKy89P15fYHt8fX4tAF8uOi0AKy0ALi1fKwAtXyoAKG51bGwpAFN1cHByZXNzaW5nIHRvbyBzcGFyc2UgdGFibGUgKHNlZSBodHRwczovL2dpdGh1Yi5jb20vbWl0eS9tZDRjL2lzc3Vlcy8zNDUpAC5fPSgpAC4rLV9+JSgpAGZhbHNlICYmICJ1bmhhbmRsZWQgTm9kZVR5cGUgaW4gbm9kZVR5cGVUb1N0cmluZyIAXCIAeyJ0eXBlIjoiAFtdIQB4WCAACgALBQAARQcAAKEEAAD2BgAAmAcAABUHAABrBwAAbwUAAE8HAADoBwAAMwgAAC0IAAC3BwAApgQAALQEAACoBgAA+wYAAB8HAAAnCAAAXQgAADIEAACLBAAAxwYAANcGAADyBwAAPAQAAKoFAADGBAAA0gQAADIFAAALBwAAAggAAHUGAABGBgBBkBcLfqgLAAATAAAAFAAAABUAAAAWAAAAFwAAAPgrAAC0CwAANCoAAE5TdDNfXzIyMF9fc2hhcmVkX3B0cl9lbXBsYWNlSU44TWFya2Rvd24xNU1hcmtkb3duQVNUTm9kZUVOU185YWxsb2NhdG9ySVMyX0VFRUUAPAUAAKMFAAAsBQBBsBgLEsIHAAA8BgAAFAUAAJAHAABMBgBB0BgLZsAMAADgDAAAEA0AAEANAAC4DAAAgA0AALgMAADADQAAIA4AALgMAAC4DAAAMA4AAFAOAABwDgAAkA4AALAOAAC4DAAAuAwAANAOAADwDgAAQA8AAFAPAAC4DAAAuAwAALgMAAC4DABBwBkLFVkFAAAHAAAAGQgAAAcAAAA4CAAABQBB4BkLHc0HAAAEAAAAAgUAAAgAAACsBwAACgAAAC0EAAAEAEGQGgsdbQYAAAcAAACjBQAABgAAAL4GAAADAAAAzwUAAAgAQcAaCzVUCAAAAgAAAGcFAAAHAAAAZAcAAAYAAACVBQAAAwAAAJQEAAADAAAA5wYAAAIAAABTBQAAAgBBgBsLNUoFAAAIAAAAagYAAAoAAADSBwAABgAAAJwFAAAGAAAAmgYAAAQAAAANCAAABQAAAEEFAAAIAEHAGwtNAgkAAAIAAAD/CAAAAgAAAPwIAAACAAAA+QgAAAIAAAD2CAAAAgAAAPMIAAACAAAAWAgAAAQAAACyBQAABgAAAJkFAAACAAAAwgYAAAQAQaAcCwUMCAAABgBBsBwLFUEIAAAGAAAALQcAAAIAAADxBgAABABB0BwLFYgGAAAEAAAAnAQAAAQAAACfBgAACABB8BwLDZgEAAADAAAAeAUAAAgAQZAdCxW/BgAAAgAAAMYFAAAIAAAAVAYAAAYAQbAdCw0+BgAAAQAAALEGAAAFAEHQHQsVXQcAAAYAAACABgAABwAAACQEAAAHAEHwHQtFIQgAAAUAAAAsBAAABQAAAD4IAAACAAAA3AQAAAUAAABCBwAAAgAAAFcIAAAFAAAAEwgAAAUAAACLBQAAAgAAAAUHAAAFAEHAHgsFtwYAAAIAQdAeCwVABgAABQBB4B4LlxMgAAAAoAAAAIAWAAAAIABACiAAgC8gAABfIAAAADAAAEEAAEBaAACAtQAAAMAAAEDWAACA2AAAQN4AAIAAAQBALgEAgDIBAEA2AQCAOQEAQEcBAIBKAQBAdgEAgHgBAAB5AQBAfQEAgH8BAACBAQAAggEAAIQBAACGAQAAhwEAAIkBAACKAQAAiwEAAI4BAACPAQAAkAEAAJEBAACTAQAAlAEAAJYBAACXAQAAmAEAAJwBAACdAQAAnwEAAKABAECkAQCApgEAAKcBAACpAQAArAEAAK4BAACvAQAAsQEAALIBAACzAQAAtQEAALcBAAC4AQAAvAEAAMQBAADFAQAAxwEAAMgBAADKAQAAywEAQNsBAIDeAQBA7gEAgPEBAADyAQAA9AEAAPYBAAD3AQAA+AEAQB4CAIAgAgAAIgIAQDICAIA6AgAAOwIAAD0CAAA+AgAAQQIAAEMCAABEAgAARQIAAEYCAEBOAgCARQMAAHADAAByAwAAdgMAAH8DAACGAwAAiAMAQIoDAICMAwAAjgMAAI8DAACRAwBAoQMAgKMDAECrAwCAwgMAAM8DAADQAwAA0QMAANUDAADWAwAA2AMAQO4DAIDwAwAA8QMAAPQDAAD1AwAA9wMAAPkDAAD6AwAA/QMAQP8DAIAABABADwQAgBAEAEAvBACAYAQAQIAEAICKBABAvgQAgMAEAADBBABAzQQAgNAEAEAuBQCAMQUAQFYFAICgEABAxRAAgMcQAADNEAAA+BMAQP0TAICAHAAAgRwAAIIcAACDHAAAhBwAAIUcAACGHAAAhxwAAIgcAACJHAAAkBwAQLocAIC9HABAvxwAgAAeAECUHgCAmx4AAKAeAED+HgCACB8AQA8fAIAYHwBAHR8AgCgfAEAvHwCAOB8AQD8fAIBIHwBATR8AgFkfAABbHwAAXR8AAF8fAABoHwBAbx8AgLgfAAC5HwAAuh8AALsfAAC+HwAAyB8AQMsfAIDYHwAA2R8AANofAADbHwAA6B8AAOkfAADqHwAA6x8AAOwfAAD4HwAA+R8AAPofAAD7HwAAJiEAACohAAArIQAAMiEAAGAhAEBvIQCAgyEAALYkAEDPJACAACwAQC8sAIBgLAAAYiwAAGMsAABkLAAAZywAQGssAIBtLAAAbiwAAG8sAABwLAAAciwAAHUsAAB+LAAAfywAAIAsAEDiLACA6ywAAO0sAADyLAAAQKYAQGymAICApgBAmqYAgCKnAEAupwCAMqcAQG6nAIB5pwAAe6cAAH2nAAB+pwBAhqcAgIunAACNpwAAkKcAAJKnAACWpwBAqKcAgKqnAACrpwAArKcAAK2nAACupwAAsKcAALGnAACypwAAs6cAALSnAEDCpwCAxKcAAMWnAADGpwAAx6cAAMmnAADLpwAAzKcAQNqnAIDcpwAA3acAAOKnAAD1pwAAbKsAAG2rAABwqwBAv6sAgCH/AEA6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")}function getBinarySync(file){if(ArrayBuffer.isView(file)){return file}if(file==wasmBinaryFile&&wasmBinary){return new Uint8Array(wasmBinary)}if(readBinary){return readBinary(file)}throw"both async and sync fetching of the wasm failed"}async function getWasmBinary(binaryFile){return getBinarySync(binaryFile)}async function instantiateArrayBuffer(binaryFile,imports){try{var binary=await getWasmBinary(binaryFile);var instance=await WebAssembly.instantiate(binary,imports);return instance}catch(reason){err(`failed to asynchronously prepare wasm: ${reason}`);abort(reason)}}async function instantiateAsync(binary,binaryFile,imports){return instantiateArrayBuffer(binaryFile,imports)}function getWasmImports(){return{env:wasmImports,wasi_snapshot_preview1:wasmImports}}async function createWasm(){function receiveInstance(instance,module){wasmExports=instance.exports;wasmMemory=wasmExports["memory"];updateMemoryViews();assignWasmExports(wasmExports);removeRunDependency("wasm-instantiate");return wasmExports}addRunDependency("wasm-instantiate");function receiveInstantiationResult(result){return receiveInstance(result["instance"])}var info=getWasmImports();if(Module["instantiateWasm"]){return new Promise((resolve,reject)=>{Module["instantiateWasm"](info,(mod,inst)=>{resolve(receiveInstance(mod,inst))})})}wasmBinaryFile??=findWasmBinary();var result=await instantiateAsync(wasmBinary,wasmBinaryFile,info);var exports=receiveInstantiationResult(result);return exports}class ExitStatus{name="ExitStatus";constructor(status){this.message=`Program terminated with exit(${status})`;this.status=status}}var callRuntimeCallbacks=callbacks=>{while(callbacks.length>0){callbacks.shift()(Module)}};var onPostRuns=[];var addOnPostRun=cb=>onPostRuns.push(cb);var onPreRuns=[];var addOnPreRun=cb=>onPreRuns.push(cb);var base64Decode=b64=>{var b1,b2,i=0,j=0,bLength=b64.length;var output=new Uint8Array((bLength*3>>2)-(b64[bLength-2]=="=")-(b64[bLength-1]=="="));for(;i>4;output[j+1]=b1<<4|b2>>2;output[j+2]=b2<<6|base64ReverseLookup[b64.charCodeAt(i+3)]}return output};var noExitRuntime=true;var stackRestore=val=>__emscripten_stack_restore(val);var stackSave=()=>_emscripten_stack_get_current();var UTF8Decoder=typeof TextDecoder!="undefined"?new TextDecoder:undefined;var UTF8ArrayToString=(heapOrArray,idx=0,maxBytesToRead=NaN)=>{var endIdx=idx+maxBytesToRead;var endPtr=idx;while(heapOrArray[endPtr]&&!(endPtr>=endIdx))++endPtr;if(endPtr-idx>16&&heapOrArray.buffer&&UTF8Decoder){return UTF8Decoder.decode(heapOrArray.subarray(idx,endPtr))}var str="";while(idx>10,56320|ch&1023)}}return str};var UTF8ToString=(ptr,maxBytesToRead)=>ptr?UTF8ArrayToString(HEAPU8,ptr,maxBytesToRead):"";var ___assert_fail=(condition,filename,line,func)=>abort(`Assertion failed: ${UTF8ToString(condition)}, at: `+[filename?UTF8ToString(filename):"unknown filename",line,func?UTF8ToString(func):"unknown function"]);class ExceptionInfo{constructor(excPtr){this.excPtr=excPtr;this.ptr=excPtr-24}set_type(type){HEAPU32[this.ptr+4>>2]=type}get_type(){return HEAPU32[this.ptr+4>>2]}set_destructor(destructor){HEAPU32[this.ptr+8>>2]=destructor}get_destructor(){return HEAPU32[this.ptr+8>>2]}set_caught(caught){caught=caught?1:0;HEAP8[this.ptr+12]=caught}get_caught(){return HEAP8[this.ptr+12]!=0}set_rethrown(rethrown){rethrown=rethrown?1:0;HEAP8[this.ptr+13]=rethrown}get_rethrown(){return HEAP8[this.ptr+13]!=0}init(type,destructor){this.set_adjusted_ptr(0);this.set_type(type);this.set_destructor(destructor)}set_adjusted_ptr(adjustedPtr){HEAPU32[this.ptr+16>>2]=adjustedPtr}get_adjusted_ptr(){return HEAPU32[this.ptr+16>>2]}}var exceptionLast=0;var uncaughtExceptionCount=0;var ___cxa_throw=(ptr,type,destructor)=>{var info=new ExceptionInfo(ptr);info.init(type,destructor);exceptionLast=ptr;uncaughtExceptionCount++;throw exceptionLast};var __abort_js=()=>abort("");var getHeapMax=()=>536870912;var alignMemory=(size,alignment)=>Math.ceil(size/alignment)*alignment;var growMemory=size=>{var b=wasmMemory.buffer;var pages=(size-b.byteLength+65535)/65536|0;try{wasmMemory.grow(pages);updateMemoryViews();return 1}catch(e){}};var _emscripten_resize_heap=requestedSize=>{var oldSize=HEAPU8.length;requestedSize>>>=0;var maxHeapSize=getHeapMax();if(requestedSize>maxHeapSize){return false}for(var cutDown=1;cutDown<=4;cutDown*=2){var overGrownHeapSize=oldSize*(1+.2/cutDown);overGrownHeapSize=Math.min(overGrownHeapSize,requestedSize+100663296);var newSize=Math.min(maxHeapSize,alignMemory(Math.max(requestedSize,overGrownHeapSize),65536));var replacement=growMemory(newSize);if(replacement){return true}}return false};var getCFunc=ident=>{var func=Module["_"+ident];return func};var writeArrayToMemory=(array,buffer)=>{HEAP8.set(array,buffer)};var lengthBytesUTF8=str=>{var len=0;for(var i=0;i=55296&&c<=57343){len+=4;++i}else{len+=3}}return len};var stringToUTF8Array=(str,heap,outIdx,maxBytesToWrite)=>{if(!(maxBytesToWrite>0))return 0;var startIdx=outIdx;var endIdx=outIdx+maxBytesToWrite-1;for(var i=0;i=endIdx)break;heap[outIdx++]=u}else if(u<=2047){if(outIdx+1>=endIdx)break;heap[outIdx++]=192|u>>6;heap[outIdx++]=128|u&63}else if(u<=65535){if(outIdx+2>=endIdx)break;heap[outIdx++]=224|u>>12;heap[outIdx++]=128|u>>6&63;heap[outIdx++]=128|u&63}else{if(outIdx+3>=endIdx)break;heap[outIdx++]=240|u>>18;heap[outIdx++]=128|u>>12&63;heap[outIdx++]=128|u>>6&63;heap[outIdx++]=128|u&63;i++}}heap[outIdx]=0;return outIdx-startIdx};var stringToUTF8=(str,outPtr,maxBytesToWrite)=>stringToUTF8Array(str,HEAPU8,outPtr,maxBytesToWrite);var stackAlloc=sz=>__emscripten_stack_alloc(sz);var stringToUTF8OnStack=str=>{var size=lengthBytesUTF8(str)+1;var ret=stackAlloc(size);stringToUTF8(str,ret,size);return ret};var ccall=(ident,returnType,argTypes,args,opts)=>{var toC={string:str=>{var ret=0;if(str!==null&&str!==undefined&&str!==0){ret=stringToUTF8OnStack(str)}return ret},array:arr=>{var ret=stackAlloc(arr.length);writeArrayToMemory(arr,ret);return ret}};function convertReturnValue(ret){if(returnType==="string"){return UTF8ToString(ret)}if(returnType==="boolean")return Boolean(ret);return ret}var func=getCFunc(ident);var cArgs=[];var stack=0;if(args){for(var i=0;i{var numericArgs=!argTypes||argTypes.every(type=>type==="number"||type==="boolean");var numericRet=returnType!=="string";if(numericRet&&numericArgs&&!opts){return getCFunc(ident)}return(...args)=>ccall(ident,returnType,argTypes,args,opts)};for(var base64ReverseLookup=new Uint8Array(123),i=25;i>=0;--i){base64ReverseLookup[48+i]=52+i;base64ReverseLookup[65+i]=i;base64ReverseLookup[97+i]=26+i}base64ReverseLookup[43]=62;base64ReverseLookup[47]=63;{if(Module["noExitRuntime"])noExitRuntime=Module["noExitRuntime"];if(Module["print"])out=Module["print"];if(Module["printErr"])err=Module["printErr"];if(Module["wasmBinary"])wasmBinary=Module["wasmBinary"];if(Module["arguments"])arguments_=Module["arguments"];if(Module["thisProgram"])thisProgram=Module["thisProgram"]}Module["ccall"]=ccall;Module["cwrap"]=cwrap;Module["UTF8ToString"]=UTF8ToString;var _parseMarkdown,__emscripten_stack_restore,__emscripten_stack_alloc,_emscripten_stack_get_current;function assignWasmExports(wasmExports){Module["_parseMarkdown"]=_parseMarkdown=wasmExports["parseMarkdown"];__emscripten_stack_restore=wasmExports["_emscripten_stack_restore"];__emscripten_stack_alloc=wasmExports["_emscripten_stack_alloc"];_emscripten_stack_get_current=wasmExports["emscripten_stack_get_current"]}var wasmImports={__assert_fail:___assert_fail,__cxa_throw:___cxa_throw,_abort_js:__abort_js,emscripten_resize_heap:_emscripten_resize_heap};var wasmExports=await createWasm();function run(){if(runDependencies>0){dependenciesFulfilled=run;return}preRun();if(runDependencies>0){dependenciesFulfilled=run;return}function doRun(){Module["calledRun"]=true;if(ABORT)return;initRuntime();readyPromiseResolve?.(Module);Module["onRuntimeInitialized"]?.();postRun()}if(Module["setStatus"]){Module["setStatus"]("Running...");setTimeout(()=>{setTimeout(()=>Module["setStatus"](""),1);doRun()},1)}else{doRun()}}function preInit(){if(Module["preInit"]){if(typeof Module["preInit"]=="function")Module["preInit"]=[Module["preInit"]];while(Module["preInit"].length>0){Module["preInit"].shift()()}}}preInit();run();if(runtimeInitialized){moduleRtn=Module}else{moduleRtn=new Promise((resolve,reject)=>{readyPromiseResolve=resolve;readyPromiseReject=reject})} ++ ++ ++ return moduleRtn; ++} ++); ++})(); ++if (typeof exports === 'object' && typeof module === 'object') { ++ module.exports = createMd4cModule; ++ // This default export looks redundant, but it allows TS to import this ++ // commonjs style module. ++ module.exports.default = createMd4cModule; ++} else if (typeof define === 'function' && define['amd']) ++ define([], () => createMd4cModule); diff --git a/node_modules/react-native-enriched-markdown/src/types/MarkdownRenderers.ts b/node_modules/react-native-enriched-markdown/src/types/MarkdownRenderers.ts new file mode 100644 --- /dev/null diff --git a/plugin-examples/local-plugin/client/icons.ts b/plugin-examples/local-plugin/client/icons.ts new file mode 100644 index 0000000000..553838556a --- /dev/null +++ b/plugin-examples/local-plugin/client/icons.ts @@ -0,0 +1,5 @@ +/** Inline SVG icon. `currentColor` follows the surface's icon color. */ +export const counterIcon = ` + + +`; diff --git a/plugin-examples/local-plugin/index.client.tsx b/plugin-examples/local-plugin/index.client.tsx index 4a95c337fc..e086b50573 100644 --- a/plugin-examples/local-plugin/index.client.tsx +++ b/plugin-examples/local-plugin/index.client.tsx @@ -1,11 +1,12 @@ import type { PluginClientContext } from "@getpaseo/plugin/client"; +import { counterIcon } from "./client/icons"; import { contributeClient, ExamplePanel } from "./client/main"; export default function contribute(client: PluginClientContext) { client.addWorkspacePanel({ id: "counter", title: "Plugin counter", - icon: "Blocks", + icon: { svg: counterIcon }, context: "workspace", locations: ["workspace", "explorer"], Component: ExamplePanel, diff --git a/plugins/cursor-usage-source/server/usage.test.ts b/plugins/cursor-usage-source/server/usage.test.ts index 91b657c264..b05159cd12 100644 --- a/plugins/cursor-usage-source/server/usage.test.ts +++ b/plugins/cursor-usage-source/server/usage.test.ts @@ -273,13 +273,50 @@ describe("cursor usage source", () => { writeFileSync(path, JSON.stringify({ accessToken: "session-token" })); } + it("keeps different accounts separate while joining global and session logins for the same account", async () => { + function token(sub: string, nonce: string) { + return `e30.${Buffer.from(JSON.stringify({ sub, nonce })).toString("base64url")}.signature`; + } + writeCursorAuthJson(homeDir, token("user-a", "desktop")); + writeCursorAuthJson(sessionHome, token("user-b", "session")); + const globalAccounts = await discover(); + const differentAccount = await discoverSession(cursorSession({}), "linux"); + expect(globalAccounts).toHaveLength(1); + expect(differentAccount).toHaveLength(1); + expect(differentAccount[0]!.key).not.toBe(globalAccounts[0]!.key); + + writeCursorAuthJson(sessionHome, token("user-a", "refreshed-session")); + const sameAccount = await discoverSession(cursorSession({}), "linux"); + expect(sameAccount).toHaveLength(1); + expect(sameAccount[0]!.key).toBe(globalAccounts[0]!.key); + }); + + it("isolates logins without a readable subject by store and keeps their key across token rotation", async () => { + writeCursorAuthJson(homeDir, "opaque-global-token"); + writeCursorAuthJson(sessionHome, "opaque-session-token"); + const globalAccounts = await discover(); + const sessionAccounts = await discoverSession(cursorSession({}), "linux"); + expect(sessionAccounts).toHaveLength(1); + expect(globalAccounts).toHaveLength(1); + expect(sessionAccounts[0]!.key).not.toBe(globalAccounts[0]!.key); + writeCursorAuthJson(sessionHome, "e30.invalid-json.signature"); + expect(await discoverSession(cursorSession({}), "linux")).toEqual(sessionAccounts); + writeCursorAuthJson(sessionHome, "e30.e30.signature"); + expect(await discoverSession(cursorSession({}), "linux")).toEqual(sessionAccounts); + }); + it("reads the login cursor-agent uses under the session's XDG_CONFIG_HOME", async () => { const configHome = join(sessionHome, "xdg"); const authPath = join(configHome, "cursor", "auth.json"); writeAuthJson(authPath); expect( await discoverSession(cursorSession({ XDG_CONFIG_HOME: configHome }), "linux"), - ).toEqual([{ key: "default", input: { store: "file", locator: authPath } }]); + ).toEqual([ + { + key: expect.stringMatching(/^store-[a-f0-9]{64}$/), + input: { store: "file", locator: authPath }, + }, + ]); }); it("reads the login under the session's HOME, not the daemon's", async () => { @@ -287,7 +324,7 @@ describe("cursor usage source", () => { writeCursorAuthJson(sessionHome, "session-token"); expect(await discoverSession(cursorSession({}), "linux")).toEqual([ { - key: "default", + key: expect.stringMatching(/^store-[a-f0-9]{64}$/), input: { store: "file", locator: join(sessionHome, ".config", "cursor", "auth.json") }, }, ]); @@ -298,7 +335,10 @@ describe("cursor usage source", () => { const authPath = join(appData, "Cursor", "auth.json"); writeAuthJson(authPath); expect(await discoverSession(cursorSession({ APPDATA: appData }), "win32")).toEqual([ - { key: "default", input: { store: "file", locator: authPath } }, + { + key: expect.stringMatching(/^store-[a-f0-9]{64}$/), + input: { store: "file", locator: authPath }, + }, ]); }); @@ -308,7 +348,12 @@ describe("cursor usage source", () => { expect(await discoverSession(cursorSession({}), "darwin")).toEqual([]); expect( await discoverSession(cursorSession({ AGENT_CLI_CREDENTIAL_STORE: "file" }), "darwin"), - ).toEqual([{ key: "default", input: { store: "file", locator: authPath } }]); + ).toEqual([ + { + key: expect.stringMatching(/^store-[a-f0-9]{64}$/), + input: { store: "file", locator: authPath }, + }, + ]); }); it.each([ @@ -341,7 +386,10 @@ it("discovery returns a locator when fetch finds cursor credentials", async () = }); expect(requested).toBe(true); expect(await discover()).toEqual([ - { key: "default", input: { store: "env", locator: "CURSOR_ACCESS_TOKEN" } }, + { + key: expect.stringMatching(/^store-[a-f0-9]{64}$/), + input: { store: "env", locator: "CURSOR_ACCESS_TOKEN" }, + }, ]); } finally { if (previous === undefined) delete process.env["CURSOR_ACCESS_TOKEN"]; diff --git a/plugins/cursor-usage-source/server/usage.ts b/plugins/cursor-usage-source/server/usage.ts index c5d2ab1391..2265dbb556 100644 --- a/plugins/cursor-usage-source/server/usage.ts +++ b/plugins/cursor-usage-source/server/usage.ts @@ -1,4 +1,5 @@ import type { UsageInput } from "../shared/input.js"; +import { createHash } from "node:crypto"; import { existsSync } from "node:fs"; import { readFile } from "node:fs/promises"; import { homedir } from "node:os"; @@ -211,6 +212,26 @@ async function readToken(input: UsageInput): Promise { return token ?? undefined; } +const CursorIdentitySchema = z.object({ sub: z.string().min(1) }); + +function cursorAccount(token: string, input: UsageInput): UsageAccount { + const parts = token.split("."); + if (parts.length === 3) { + try { + const payload: unknown = JSON.parse(Buffer.from(parts[1]!, "base64url").toString("utf8")); + const identity = CursorIdentitySchema.safeParse(payload); + if (identity.success) { + const key = createHash("sha256").update(identity.data.sub).digest("hex"); + return { key: `account-${key}`, input }; + } + } catch { + // Non-JWT logins still have a usage card, isolated to their credential store. + } + } + const key = createHash("sha256").update(JSON.stringify(input)).digest("hex"); + return { key: `store-${key}`, input }; +} + export async function discover(): Promise { const home = homedir(); const candidates: UsageInput[] = ["CURSOR_ACCESS_TOKEN", "CURSOR_TOKEN"].map((locator) => ({ @@ -237,12 +258,14 @@ export async function discover(): Promise { ].map((locator) => ({ store: "sqlite" as const, locator })), { store: "file", locator: join(home, ".config", "cursor", "auth.json") }, ); - for (const input of candidates) if (await readToken(input)) return [{ key: "default", input }]; + for (const input of candidates) { + const token = await readToken(input); + if (token) return [cursorAccount(token, input)]; + } return []; } -// Resolves the login a cursor-agent session runs on. The key matches global discovery so -// the session's login joins the host's Cursor card instead of adding a second one. +// Account identity joins global and session logins without merging different users. export async function discoverSession( scope: Extract, platform: NodeJS.Platform = process.platform, @@ -251,7 +274,8 @@ export async function discoverSession( const locator = cursorAgentAuthPath(scope.env, platform); if (!locator) return []; const input: UsageInput = { store: "file", locator }; - return (await readToken(input)) ? [{ key: "default", input }] : []; + const token = await readToken(input); + return token ? [cursorAccount(token, input)] : []; } // Mirrors cursor-agent's credential store. Env credentials win over the stored login and diff --git a/plugins/package.json b/plugins/package.json index 8f37f073c8..56f39fb45c 100644 --- a/plugins/package.json +++ b/plugins/package.json @@ -1,6 +1,6 @@ { "name": "@getpaseo/builtin-plugins", - "version": "0.12.0-beta.1", + "version": "0.12.0", "private": true, "type": "module", "scripts": { diff --git a/public-docs/plugins/index.md b/public-docs/plugins/index.md index 50d9be9826..b21a637ffa 100644 --- a/public-docs/plugins/index.md +++ b/public-docs/plugins/index.md @@ -222,7 +222,8 @@ client.addCommandCenterItem({ }); ``` -`icon` is a [Lucide](https://lucide.dev/icons/) icon name. +`icon` is a [Lucide](https://lucide.dev/icons/) icon name, inline SVG, or a component. See +[Icons](/docs/plugins/reference#icons). ## Edit and reload diff --git a/public-docs/plugins/reference.md b/public-docs/plugins/reference.md index cc8023b251..7a05329116 100644 --- a/public-docs/plugins/reference.md +++ b/public-docs/plugins/reference.md @@ -162,7 +162,7 @@ guarantee compatibility with another host's renderer. These exact module specifiers use the host's runtime instances. A client bundle that requests another host module fails with `Module "" is not available in plugin client code`. -Do not import `lucide-react-native`, `react-native-svg`, or DOM libraries. Set contribution `icon` fields to a [Lucide icon name](https://lucide.dev/icons/); Paseo validates the name and renders the icon. +Do not import `lucide-react-native`, `react-native-svg`, or DOM libraries. Set contribution `icon` fields to a [Lucide icon name](https://lucide.dev/icons/), inline SVG, or a component; Paseo validates the icon and renders it. See [Icons](#icons). ### Cross-platform rules @@ -338,11 +338,9 @@ Use `runAcpProvider()` from `@getpaseo/plugin/server/acp` to adapt a command-bac hooks only for a vendor's discovery, configuration, notification, or tool-call differences. `ProviderRegistration.icon` is a file path relative to the plugin directory, such as `icon.svg`. -It must resolve inside that directory to a regular SVG file no larger than 64 KiB. The SVG must be -self-contained: scripts, styles, `foreignObject`, event-handler attributes, JavaScript URLs, and -external `href` or `xlink:href` references are rejected. Fragment references such as `#mark` are -allowed. Paseo reads and sanitizes the file when the plugin starts; the string is never an inline -SVG or URL. +It must resolve inside that directory to a regular file that follows the +[SVG icon rules](#svg-rules). Paseo reads and validates the file when the plugin starts; the string +is never inline SVG or a URL. ### Usage sources @@ -516,7 +514,7 @@ bypasses that cache. Entries carry `id`, `account.label`, and `fetchedAt`. Faile on `server_info.features.usageSources`. The older `provider.usage.list` RPC maps the same reports for 0.10 clients and renders problems into its `error` string. -The source icon follows the provider SVG restrictions above. +The source icon is a file path with the same rules as a provider icon. ## Entry point and cleanup @@ -968,10 +966,10 @@ closes the popover. Render the item with the sidebar kit from `@getpaseo/plugin/client/ui`: -| Component | Props and behavior | -| ------------------ | --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | -| `SidebarRow` | Required `onPress`; optional `icon` (Lucide name or `{ size, color }` component), `label`, `active`, `trailing`, `id`. A full-width row. `trailing` renders beside the row's pressable, so a button in it presses on its own; a press elsewhere in it presses the row. `id` tells rows of one item apart in test IDs. | -| `SidebarSeparator` | No props. The sidebar's separator line, between groups of rows. | +| Component | Props and behavior | +| ------------------ | -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | +| `SidebarRow` | Required `onPress`; optional `icon` (any [icon](#icons) form), `label`, `active`, `trailing`, `id`. A full-width row. `trailing` renders beside the row's pressable, so a button in it presses on its own; a press elsewhere in it presses the row. `id` tells rows of one item apart in test IDs. | +| `SidebarSeparator` | No props. The sidebar's separator line, between groups of rows. | A popover anchors to the row that was pressed, whether the press landed on the row or on its `trailing` content, so a per-row "More" button opens its popover next to its own row. @@ -1246,14 +1244,82 @@ Showing another toast replaces the currently visible toast. An empty message is ### Icons -`Icon` renders a [Lucide icon](https://lucide.dev/icons/) from Paseo's installed icon set. Plugin bundles do not import -`lucide-react-native` or `react-native-svg`. +Every contribution `icon` field takes one of three forms, typed `PluginIcon` in +`@getpaseo/plugin/client`: -| Prop | Type | Required | Behavior | -| ------- | -------- | -------- | ----------------------------------------------- | -| `name` | `string` | Yes | Lucide icon name. Unknown names render nothing. | -| `size` | `number` | No | Icon width and height. | -| `color` | `string` | No | Icon color. Use a plugin theme token. | +| Form | Example | Use it for | +| ----------- | --------------------------- | --------------------------------------------------- | +| Lucide name | `icon: "Scan"` | Any [Lucide icon](https://lucide.dev/icons/). | +| Inline SVG | `icon: { svg: reviewIcon }` | A brand mark or an icon Lucide does not have. | +| Component | `icon: ReviewBadge` | An icon that changes with state, such as a counter. | + +Attachment sources take a Lucide name or inline SVG (`PluginSerializableIcon`), because each +attached item stores its source's icon. + +Paseo validates the icon when the contribution registers. An unknown Lucide name or an SVG that +breaks a rule fails the plugin with the reason: + +```text +Workspace panel review has an invalid icon: script elements are not allowed +``` + +Paseo draws inline SVG at the surface's icon size and passes the surface's icon color as +`currentColor`. Paint with `currentColor` to follow the theme; fixed fills keep their colors. + +A component receives `PluginIconProps`, `{ size, color }`, and renders within that size. Header +buttons and composer pills pass [`PluginButtonIconProps`](#custom-icons-and-popover-content). + +#### SVG rules + +Inline SVG, provider icons, and usage-source icons follow the same rules: + +- One `` document, no larger than 64 KiB. +- No `