[
  {
    "path": ".eslintrc.cjs",
    "content": "// Copyright 2021-2023 The Connect Authors\n//\n// Licensed under the Apache License, Version 2.0 (the \"License\");\n// you may not use this file except in compliance with the License.\n// You may obtain a copy of the License at\n//\n//      http://www.apache.org/licenses/LICENSE-2.0\n//\n// Unless required by applicable law or agreed to in writing, software\n// distributed under the License is distributed on an \"AS IS\" BASIS,\n// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n// See the License for the specific language governing permissions and\n// limitations under the License.\n\nmodule.exports = {\n  env: {\n    browser: true,\n    es2021: true,\n    node: true,\n  },\n  root: true,\n  ignorePatterns: [\"packages/*/dist/**\"],\n  plugins: [\"@typescript-eslint\", \"n\", \"import\", \"vitest\"],\n  // Rules and settings that do not require a non-default parser\n  extends: [\"eslint:recommended\"],\n  rules: {\n    \"no-console\": \"error\",\n    \"import/no-cycle\": \"error\",\n    \"import/no-duplicates\": \"error\",\n  },\n  overrides: [\n    {\n      files: [\"**/*.{ts,tsx,cts,mts}\"],\n      parser: \"@typescript-eslint/parser\",\n      parserOptions: {\n        project: true,\n      },\n      settings: {\n        \"import/resolver\": {\n          typescript: {\n            project: \"tsconfig.json\",\n          },\n        },\n      },\n      extends: [\n        \"plugin:@typescript-eslint/recommended\",\n        \"plugin:@typescript-eslint/recommended-requiring-type-checking\",\n        \"plugin:import/recommended\",\n        \"plugin:import/typescript\",\n      ],\n      rules: {\n        \"@typescript-eslint/strict-boolean-expressions\": \"error\",\n        \"@typescript-eslint/no-unnecessary-condition\": \"error\",\n        \"@typescript-eslint/array-type\": \"off\", // we use complex typings, where Array is actually more readable than T[]\n        \"@typescript-eslint/switch-exhaustiveness-check\": [\n          \"error\",\n          {\n            considerDefaultExhaustiveForUnions: true,\n          },\n        ],\n        \"@typescript-eslint/prefer-nullish-coalescing\": \"error\",\n        \"@typescript-eslint/no-unnecessary-boolean-literal-compare\": \"error\",\n        \"@typescript-eslint/no-invalid-void-type\": \"error\",\n        \"@typescript-eslint/no-base-to-string\": \"error\",\n        \"import/no-cycle\": \"error\",\n        \"import/no-duplicates\": \"error\",\n      },\n    },\n    // For scripts and configurations, use Node.js rules\n    {\n      files: [\"**/*.{js,mjs,cjs}\"],\n      parserOptions: {\n        ecmaVersion: 13, // ES2022 - https://eslint.org/docs/latest/use/configure/language-options#specifying-environments\n      },\n      extends: [\"eslint:recommended\", \"plugin:n/recommended\"],\n      rules: {\n        \"n/hashbang\": \"off\", // this rule reports _any_ hashbang outside of an npm binary as an error\n        \"n/prefer-global/process\": \"off\",\n        \"n/no-process-exit\": \"off\",\n        \"n/exports-style\": [\"error\", \"module.exports\"],\n        \"n/file-extension-in-import\": [\"error\", \"always\"],\n        \"n/prefer-global/buffer\": [\"error\", \"always\"],\n        \"n/prefer-global/console\": [\"error\", \"always\"],\n        \"n/prefer-global/url-search-params\": [\"error\", \"always\"],\n        \"n/prefer-global/url\": [\"error\", \"always\"],\n        \"n/prefer-promises/dns\": \"error\",\n        \"n/prefer-promises/fs\": \"error\",\n        \"n/no-unsupported-features/node-builtins\": \"error\",\n        \"n/no-unsupported-features/es-syntax\": \"error\",\n      },\n    },\n  ],\n};\n"
  },
  {
    "path": ".gitattributes",
    "content": "# This is similar to the git option core.autocrlf but it applies to all\n# users of the repository and therefore doesn't depend on a developers\n# local configuration.\n* text=auto\n\n# Ignore generated files in GitHub diffs by default\n**/*_pb.ts linguist-generated=true\n**/*_connect.ts linguist-generated=true\n**/*_pb.js linguist-generated=true\n**/*_pb.d.ts linguist-generated=true\n"
  },
  {
    "path": ".github/CODE_OF_CONDUCT.md",
    "content": "## Community Code of Conduct\n\nConnect follows the [CNCF Code of Conduct](https://github.com/cncf/foundation/blob/master/code-of-conduct.md).\n"
  },
  {
    "path": ".github/CONTRIBUTING.md",
    "content": "# Contributing\n\nWe'd love your help making `connect-query-es` better!\n\nIf you'd like to add new exported APIs, please [open an issue][open-issue]\ndescribing your proposal &mdash; discussing API changes ahead of time makes\npull request review much smoother. In your issue, pull request, and any other\ncommunications, please remember to treat your fellow contributors with\nrespect!\n\nNote that for a contribution to be accepted, you must sign off on all commits\nin order to affirm that they comply with the [Developer Certificate of Origin][dco].\nMake sure to configure `git` with the same name and E-Mail as your GitHub account,\nand run `git commit` with the `-s` flag to sign. If necessary, a bot will remind\nyou to sign your commits when you open your pull request, and provide helpful tips.\n\n## Setup\n\n[Fork][fork], then clone the repository:\n\n```\ngit clone git@github.com:your_github_username/connect-query-es.git\ncd connect-query-es\ngit remote add upstream https://github.com/connectrpc/connect-query-es.git\ngit fetch upstream\n```\n\nInstall dependencies (you'll need Node.js in the version specified in `.nvmrc`,\nand `npm` in the version specified in `package.json`):\n\n```bash\nnpm ci\n```\n\nMake sure that the tests, linters, and other checks pass:\n\n```bash\nnpm run all\n```\n\nWe're using `turborepo` to run tasks. If you haven't used it yet, take a look at\n[filtering and package scoping](https://turbo.build/repo/docs/crafting-your-repository/running-tasks).\n\n## Making Changes\n\nStart by creating a new branch for your changes:\n\n```\ngit checkout main\ngit fetch upstream\ngit rebase upstream/main\ngit checkout -b cool_new_feature\n```\n\nMake your changes, then ensure that `npm run all` still passes.\nWhen you're satisfied with your changes, push them to your fork.\n\n```\ngit commit -a\ngit push origin cool_new_feature\n```\n\nThen use the GitHub UI to open a pull request.\n\nAt this point, you're waiting on us to review your changes. We _try_ to respond\nto issues and pull requests within a few business days, and we may suggest some\nimprovements or alternatives. Once your changes are approved, one of the\nproject maintainers will merge them.\n\nWe're much more likely to approve your changes if you:\n\n- Add tests for new functionality.\n- Write a [good commit message][commit-message].\n- Maintain backward compatibility.\n\n[fork]: https://github.com/connectrpc/connect-query-es/fork\n[open-issue]: https://github.com/connectrpc/connect-query-es/issues/new\n[dco]: https://developercertificate.org\n[commit-message]: http://tbaggery.com/2008/04/19/a-note-about-git-commit-messages.html\n"
  },
  {
    "path": ".github/RELEASING.md",
    "content": "# Releasing\n\n## Prerequisites\n\n- See the setup and tools required in CONTRIBUTING.md\n- A granular access token for npmjs.com with read and write permissions, scoped\n  to the `connectrpc` organization.\n- Make sure that the repository is in a good state, without PRs close to merge\n  that would ideally be part of the release.\n\n## Steps\n\n1. Choose a new version (e.g. 1.2.3), making sure to follow semver. Note that all\n   packages in this repository use the same version number.\n2. Trigger the prepare-release workflow that will create a release PR.\n\n- Note: If releasing for a hotfix of a major version that is behind the current main branch, make sure to create an appropriate branch (e.g. release/v1.x) before running the workflow with the branch name set as the base_branch.\n\n3. Edit the PR description with release notes. See the section below for details.\n4. Make sure CI passed on your PR and ask a maintainer for review.\n5. After approval, merge your PR.\n\n## Release notes\n\n- We generate release notes with the GitHub feature, see\n  https://docs.github.com/en/repositories/releasing-projects-on-github/automatically-generated-release-notes\n- Only changes that impact users should be listed. No need to list things like\n  doc changes (unless it’s something major), dependency version bumps, or similar.\n  Remove them from the generated release notes.\n- If the release introduces a major new feature or change, add a section at the\n  top that explains it for users. A good example is https://github.com/connectrpc/connect-es/releases/tag/v0.10.0\n  It lists a major new feature and a major change with dedicated sections, and\n  moves the changelist with PR links to a separate \"Enhancement\" section below.\n- If the release includes a very long list of changes, consider breaking the\n  changelist up with the sections \"Enhancements\", \"Bugfixes\", \"Breaking changes\".\n  A good example is https://github.com/connectrpc/connect-es/releases/tag/v0.9.0\n- If the release includes changes specific to a npm package, group and explain\n  the changelist in according separate sections. A good example is https://github.com/connectrpc/connect-es/releases/tag/v0.8.0\n  Note that we are not using full package names with scope - a more user-friendly\n  name like \"Connect for Node.js\" or \"Connect for Fastify\" is preferable.\n"
  },
  {
    "path": ".github/dependabot.yaml",
    "content": "version: 2\nupdates:\n  - package-ecosystem: \"github-actions\"\n    directory: \"/\"\n    schedule:\n      interval: \"monthly\"\n      day: \"monday\"\n      timezone: UTC\n      time: \"07:00\"\n  - package-ecosystem: \"npm\"\n    directory: \"/\"\n    schedule:\n      interval: \"monthly\"\n      day: \"monday\"\n      timezone: UTC\n      time: \"07:00\"\n    open-pull-requests-limit: 50\n    groups:\n      connectRelated:\n        patterns:\n          - \"@connectrpc/*\"\n          - \"@bufbuild/*\"\n      devDependencies:\n        patterns:\n          - \"@arethetypeswrong/*\"\n          - \"@testing-library/*\"\n          - \"@types/*\"\n          - \"@typescript-eslint/*\"\n          - \"@vitejs/*\"\n          - \"cspell\"\n          - \"eslint*\"\n          - \"jest-mock\"\n          - \"jest\"\n          - \"prettier\"\n          - \"react-dom\"\n          - \"react\"\n          - \"ts-jest\"\n          - \"ts-node\"\n          - \"turbo\"\n          - \"typescript\"\n          - \"vite\"\n          - \"vitest\"\n          - \"@vitest/*\"\n      reactQuery:\n        patterns:\n          - \"@tanstack/react-query\"\n          - \"@tanstack/react-query-devtools\"\n          - \"@tanstack/query-core\"\n"
  },
  {
    "path": ".github/release.yaml",
    "content": "changelog:\n  exclude:\n    labels:\n      - ignore-for-release\n    authors:\n      - dependabot[bot]\n"
  },
  {
    "path": ".github/workflows/add-to-project.yaml",
    "content": "name: Add issues and PRs to project\n\non:\n  issues:\n    types:\n      - opened\n      - reopened\n      - transferred\n  pull_request_target:\n    types:\n      - opened\n      - reopened\n  issue_comment:\n    types:\n      - created\n\njobs:\n  call-workflow-add-to-project:\n    name: Call workflow to add issue to project\n    uses: connectrpc/base-workflows/.github/workflows/add-to-project.yaml@main\n    secrets: inherit\n"
  },
  {
    "path": ".github/workflows/ci.yaml",
    "content": "name: ci\n\non:\n  push:\n    branches: [main, \"v*\"]\n    tags: [\"v*\"]\n  pull_request:\n    branches: [main, \"v*\"]\n  workflow_dispatch:\n\npermissions:\n  contents: read\n\nenv:\n  # https://consoledonottrack.com/\n  DO_NOT_TRACK: 1\n\njobs:\n  tasks:\n    runs-on: ubuntu-22.04\n    strategy:\n      fail-fast: false\n      matrix:\n        task:\n          - format\n          - license-header\n          - lint\n          - attw\n          - build\n        include:\n          - task: format\n            diff-check: true\n          - task: license-header\n            diff-check: true\n    name: ${{ matrix.task }}\n    steps:\n      - uses: actions/checkout@v6\n      - uses: actions/setup-node@v6\n        with:\n          node-version-file: .nvmrc\n          cache: \"npm\"\n      - uses: actions/cache@v5\n        with:\n          path: .turbo\n          key: ${{ runner.os }}/${{ matrix.task }}/${{ github.sha }}\n          restore-keys: ${{ runner.os }}/${{ matrix.task }}\n      - run: npm ci\n      - run: npx turbo run ${{ matrix.task }}\n      - name: Check changed files\n        if: ${{ matrix.diff-check }}\n        run: node scripts/gh-diffcheck.js\n  test:\n    runs-on: ubuntu-22.04\n    strategy:\n      fail-fast: false\n      matrix:\n        node-version: [24.x, 22.x, 20.x]\n    name: \"test on Node.js ${{ matrix.node-version }}\"\n    steps:\n      - uses: actions/checkout@v6\n      - uses: actions/setup-node@v6\n        with:\n          node-version: ${{ matrix.node-version }}\n          cache: \"npm\"\n      - uses: actions/cache@v5\n        with:\n          path: .turbo\n          key: ${{ runner.os }}/test/${{ github.sha }}\n          restore-keys: ${{ runner.os }}/test\n      - run: npm ci\n      - run: npx turbo run test\n"
  },
  {
    "path": ".github/workflows/pr-title.yaml",
    "content": "name: Lint PR Title\n# Prevent writing to the repository using the CI token.\n# Ref: https://docs.github.com/en/actions/reference/workflow-syntax-for-github-actions#permissions\npermissions:\n  pull-requests: read\non:\n  pull_request:\n    # By default, a workflow only runs when a pull_request's activity type is opened,\n    # synchronize, or reopened. We explicity override here so that PR titles are\n    # re-linted when the PR text content is edited.\n    types:\n      - opened\n      - edited\n      - reopened\n      - synchronize\njobs:\n  lint:\n    uses: bufbuild/base-workflows/.github/workflows/pr-title.yaml@main\n"
  },
  {
    "path": ".github/workflows/prepare-release.yml",
    "content": "name: Prepare Release\n\non:\n  workflow_dispatch:\n    inputs:\n      version:\n        description: \"Version to release (e.g. 1.2.3)\"\n        required: true\n        type: string\n\njobs:\n  prepare-release:\n    runs-on: ubuntu-latest\n    permissions:\n      contents: write\n      pull-requests: write\n\n    steps:\n      - name: Checkout repository\n        uses: actions/checkout@v6\n        with:\n          ref: main\n          fetch-depth: 0\n          token: ${{ secrets.GITHUB_TOKEN }}\n\n      - name: Setup Node.js\n        uses: actions/setup-node@v6\n        with:\n          node-version-file: \".nvmrc\"\n\n      - name: Install dependencies\n        run: npm ci\n\n      - name: Create release branch\n        run: |\n          git config --global user.name 'github-actions[bot]'\n          git config --global user.email 'github-actions[bot]@users.noreply.github.com'\n          git checkout -b \"release/prep-release-${{ inputs.version }}\"\n\n      - name: Get current workspace version\n        id: workspace_version\n        run: |\n          VERSION=$(npm run getversion --silent)\n          echo \"version=$VERSION\" >> $GITHUB_OUTPUT\n\n      - name: Set version and run build\n        run: |\n          npm run setversion ${{ inputs.version }}\n\n      - name: Commit version changes\n        run: |\n          git add .\n          git commit -s -m \"Release ${{ inputs.version }}\"\n          git push --set-upstream origin \"release/prep-release-${{ inputs.version }}\"\n\n      - name: Get release notes\n        id: release_notes\n        run: |\n          RELEASE_NOTES=$(\n            gh api \\\n              --method POST \\\n              -H \"Accept: application/vnd.github+json\" \\\n              -H \"X-GitHub-Api-Version: 2022-11-28\" \\\n              /repos/${{ github.repository }}/releases/generate-notes \\\n              -f 'tag_name=v${{ inputs.version }}' -f 'target_commitish=${{ inputs.base_branch }}' -f 'previous_tag_name=v${{ steps.workspace_version.outputs.version }}' \\\n              --jq \".body\" \\\n          )\n          echo \"notes<<EOF\" >> $GITHUB_OUTPUT\n          echo \"$RELEASE_NOTES\" >> $GITHUB_OUTPUT\n          echo \"EOF\" >> $GITHUB_OUTPUT\n        env:\n          GH_TOKEN: ${{ secrets.GITHUB_TOKEN }}\n\n      - name: Create pull request\n        run: |\n          gh pr create \\\n            --title \"Release ${{ inputs.version }}\" \\\n            --body \"${{ steps.release_notes.outputs.notes }}\" \\\n            --base \"${{ inputs.base_branch }}\"\n        env:\n          GH_TOKEN: ${{ secrets.GITHUB_TOKEN }}\n"
  },
  {
    "path": ".github/workflows/publish-release.yml",
    "content": "name: Publish Release\n\non:\n  pull_request:\n    types: [closed]\n    branches:\n      - main\n\njobs:\n  publish-release:\n    runs-on: ubuntu-latest\n    # Only run if PR was merged and branch name starts with release/prep-release-\n    if: github.event.pull_request.merged == true && startsWith(github.event.pull_request.head.ref, 'release/prep-release-')\n    permissions:\n      id-token: write # Required for OIDC\n      contents: write\n      pull-requests: write\n      issues: write\n\n    steps:\n      - name: Checkout base branch\n        uses: actions/checkout@v6\n        with:\n          ref: ${{ github.event.pull_request.base.ref }}\n          fetch-depth: 0\n          token: ${{ secrets.GITHUB_TOKEN }}\n\n      - name: Setup Node.js\n        uses: actions/setup-node@v6\n        with:\n          node-version-file: \".nvmrc\"\n\n      - name: Install dependencies\n        run: npm ci\n\n      - name: Get current workspace version\n        id: workspace_version\n        run: |\n          VERSION=$(npm run getversion --silent)\n          echo \"version=$VERSION\" >> $GITHUB_OUTPUT\n\n      - name: Get updated release notes from PR\n        id: pr_notes\n        run: |\n          RELEASE_NOTES=$(gh pr view ${{ github.event.pull_request.number }} --json body | jq -r \".body\")\n          echo \"notes<<EOF\" >> $GITHUB_OUTPUT\n          echo \"$RELEASE_NOTES\" >> $GITHUB_OUTPUT\n          echo \"EOF\" >> $GITHUB_OUTPUT\n        env:\n          GH_TOKEN: ${{ secrets.GITHUB_TOKEN }}\n\n      - name: Publish to npm\n        run: npm run release\n\n      - name: Publish GitHub release\n        run: |\n          gh release create v${{ steps.workspace_version.outputs.version }} \\\n            --title \"Release v${{ steps.workspace_version.outputs.version }}\" \\\n            --notes \"${{ steps.pr_notes.outputs.notes }}\"\n        # --discussion-category \"Announcements\" ## Enable if discussions are enabled\n        env:\n          GH_TOKEN: ${{ secrets.GITHUB_TOKEN }}\n"
  },
  {
    "path": ".gitignore",
    "content": ".turbo\n.wrangler\nnode_modules\n/packages/*/dist\n/packages/*/coverage\ntsconfig.vitest-temp.json"
  },
  {
    "path": ".nvmrc",
    "content": "v24.5.0\n"
  },
  {
    "path": ".vscode/extensions.json",
    "content": "{\n  \"recommendations\": [\"orta.vscode-twoslash-queries\"]\n}\n"
  },
  {
    "path": ".vscode/settings.json",
    "content": "{\n  \"git.enableCommitSigning\": true,\n  \"git.alwaysSignOff\": true,\n  \"typescript.tsdk\": \"node_modules/typescript/lib\"\n}\n"
  },
  {
    "path": "LICENSE",
    "content": "                                 Apache License\n                           Version 2.0, January 2004\n                        http://www.apache.org/licenses/\n\nTERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION\n\n1.  Definitions.\n\n    \"License\" shall mean the terms and conditions for use, reproduction,\n    and distribution as defined by Sections 1 through 9 of this document.\n\n    \"Licensor\" shall mean the copyright owner or entity authorized by\n    the copyright owner that is granting the License.\n\n    \"Legal Entity\" shall mean the union of the acting entity and all\n    other entities that control, are controlled by, or are under common\n    control with that entity. For the purposes of this definition,\n    \"control\" means (i) the power, direct or indirect, to cause the\n    direction or management of such entity, whether by contract or\n    otherwise, or (ii) ownership of fifty percent (50%) or more of the\n    outstanding shares, or (iii) beneficial ownership of such entity.\n\n    \"You\" (or \"Your\") shall mean an individual or Legal Entity\n    exercising permissions granted by this License.\n\n    \"Source\" form shall mean the preferred form for making modifications,\n    including but not limited to software source code, documentation\n    source, and configuration files.\n\n    \"Object\" form shall mean any form resulting from mechanical\n    transformation or translation of a Source form, including but\n    not limited to compiled object code, generated documentation,\n    and conversions to other media types.\n\n    \"Work\" shall mean the work of authorship, whether in Source or\n    Object form, made available under the License, as indicated by a\n    copyright notice that is included in or attached to the work\n    (an example is provided in the Appendix below).\n\n    \"Derivative Works\" shall mean any work, whether in Source or Object\n    form, that is based on (or derived from) the Work and for which the\n    editorial revisions, annotations, elaborations, or other modifications\n    represent, as a whole, an original work of authorship. For the purposes\n    of this License, Derivative Works shall not include works that remain\n    separable from, or merely link (or bind by name) to the interfaces of,\n    the Work and Derivative Works thereof.\n\n    \"Contribution\" shall mean any work of authorship, including\n    the original version of the Work and any modifications or additions\n    to that Work or Derivative Works thereof, that is intentionally\n    submitted to Licensor for inclusion in the Work by the copyright owner\n    or by an individual or Legal Entity authorized to submit on behalf of\n    the copyright owner. For the purposes of this definition, \"submitted\"\n    means any form of electronic, verbal, or written communication sent\n    to the Licensor or its representatives, including but not limited to\n    communication on electronic mailing lists, source code control systems,\n    and issue tracking systems that are managed by, or on behalf of, the\n    Licensor for the purpose of discussing and improving the Work, but\n    excluding communication that is conspicuously marked or otherwise\n    designated in writing by the copyright owner as \"Not a Contribution.\"\n\n    \"Contributor\" shall mean Licensor and any individual or Legal Entity\n    on behalf of whom a Contribution has been received by Licensor and\n    subsequently incorporated within the Work.\n\n2.  Grant of Copyright License. Subject to the terms and conditions of\n    this License, each Contributor hereby grants to You a perpetual,\n    worldwide, non-exclusive, no-charge, royalty-free, irrevocable\n    copyright license to reproduce, prepare Derivative Works of,\n    publicly display, publicly perform, sublicense, and distribute the\n    Work and such Derivative Works in Source or Object form.\n\n3.  Grant of Patent License. Subject to the terms and conditions of\n    this License, each Contributor hereby grants to You a perpetual,\n    worldwide, non-exclusive, no-charge, royalty-free, irrevocable\n    (except as stated in this section) patent license to make, have made,\n    use, offer to sell, sell, import, and otherwise transfer the Work,\n    where such license applies only to those patent claims licensable\n    by such Contributor that are necessarily infringed by their\n    Contribution(s) alone or by combination of their Contribution(s)\n    with the Work to which such Contribution(s) was submitted. If You\n    institute patent litigation against any entity (including a\n    cross-claim or counterclaim in a lawsuit) alleging that the Work\n    or a Contribution incorporated within the Work constitutes direct\n    or contributory patent infringement, then any patent licenses\n    granted to You under this License for that Work shall terminate\n    as of the date such litigation is filed.\n\n4.  Redistribution. You may reproduce and distribute copies of the\n    Work or Derivative Works thereof in any medium, with or without\n    modifications, and in Source or Object form, provided that You\n    meet the following conditions:\n\n    (a) You must give any other recipients of the Work or\n    Derivative Works a copy of this License; and\n\n    (b) You must cause any modified files to carry prominent notices\n    stating that You changed the files; and\n\n    (c) You must retain, in the Source form of any Derivative Works\n    that You distribute, all copyright, patent, trademark, and\n    attribution notices from the Source form of the Work,\n    excluding those notices that do not pertain to any part of\n    the Derivative Works; and\n\n    (d) If the Work includes a \"NOTICE\" text file as part of its\n    distribution, then any Derivative Works that You distribute must\n    include a readable copy of the attribution notices contained\n    within such NOTICE file, excluding those notices that do not\n    pertain to any part of the Derivative Works, in at least one\n    of the following places: within a NOTICE text file distributed\n    as part of the Derivative Works; within the Source form or\n    documentation, if provided along with the Derivative Works; or,\n    within a display generated by the Derivative Works, if and\n    wherever such third-party notices normally appear. The contents\n    of the NOTICE file are for informational purposes only and\n    do not modify the License. You may add Your own attribution\n    notices within Derivative Works that You distribute, alongside\n    or as an addendum to the NOTICE text from the Work, provided\n    that such additional attribution notices cannot be construed\n    as modifying the License.\n\n    You may add Your own copyright statement to Your modifications and\n    may provide additional or different license terms and conditions\n    for use, reproduction, or distribution of Your modifications, or\n    for any such Derivative Works as a whole, provided Your use,\n    reproduction, and distribution of the Work otherwise complies with\n    the conditions stated in this License.\n\n5.  Submission of Contributions. Unless You explicitly state otherwise,\n    any Contribution intentionally submitted for inclusion in the Work\n    by You to the Licensor shall be under the terms and conditions of\n    this License, without any additional terms or conditions.\n    Notwithstanding the above, nothing herein shall supersede or modify\n    the terms of any separate license agreement you may have executed\n    with Licensor regarding such Contributions.\n\n6.  Trademarks. This License does not grant permission to use the trade\n    names, trademarks, service marks, or product names of the Licensor,\n    except as required for reasonable and customary use in describing the\n    origin of the Work and reproducing the content of the NOTICE file.\n\n7.  Disclaimer of Warranty. Unless required by applicable law or\n    agreed to in writing, Licensor provides the Work (and each\n    Contributor provides its Contributions) on an \"AS IS\" BASIS,\n    WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or\n    implied, including, without limitation, any warranties or conditions\n    of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A\n    PARTICULAR PURPOSE. You are solely responsible for determining the\n    appropriateness of using or redistributing the Work and assume any\n    risks associated with Your exercise of permissions under this License.\n\n8.  Limitation of Liability. In no event and under no legal theory,\n    whether in tort (including negligence), contract, or otherwise,\n    unless required by applicable law (such as deliberate and grossly\n    negligent acts) or agreed to in writing, shall any Contributor be\n    liable to You for damages, including any direct, indirect, special,\n    incidental, or consequential damages of any character arising as a\n    result of this License or out of the use or inability to use the\n    Work (including but not limited to damages for loss of goodwill,\n    work stoppage, computer failure or malfunction, or any and all\n    other commercial damages or losses), even if such Contributor\n    has been advised of the possibility of such damages.\n\n9.  Accepting Warranty or Additional Liability. While redistributing\n    the Work or Derivative Works thereof, You may choose to offer,\n    and charge a fee for, acceptance of support, warranty, indemnity,\n    or other liability obligations and/or rights consistent with this\n    License. However, in accepting such obligations, You may act only\n    on Your own behalf and on Your sole responsibility, not on behalf\n    of any other Contributor, and only if You agree to indemnify,\n    defend, and hold each Contributor harmless for any liability\n    incurred by, or claims asserted against, such Contributor by reason\n    of your accepting any such warranty or additional liability.\n\nEND OF TERMS AND CONDITIONS\n\nAPPENDIX: How to apply the Apache License to your work.\n\n      To apply the Apache License to your work, attach the following\n      boilerplate notice, with the fields enclosed by brackets \"[]\"\n      replaced with your own identifying information. (Don't include\n      the brackets!)  The text should be enclosed in the appropriate\n      comment syntax for the file format. We also recommend that a\n      file or class name and description of purpose be included on the\n      same \"printed page\" as the copyright notice for easier\n      identification within third-party archives.\n\nCopyright 2021-2023 The Connect Authors\n\nLicensed under the Apache License, Version 2.0 (the \"License\");\nyou may not use this file except in compliance with the License.\nYou may obtain a copy of the License at\n\n       http://www.apache.org/licenses/LICENSE-2.0\n\nUnless required by applicable law or agreed to in writing, software\ndistributed under the License is distributed on an \"AS IS\" BASIS,\nWITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\nSee the License for the specific language governing permissions and\nlimitations under the License.\n"
  },
  {
    "path": "MAINTAINERS.md",
    "content": "# Maintainers\n\n## Current\n\n- [Timo Stamm](https://github.com/timostamm), [Buf](https://buf.build)\n- [Steve Ayers](https://github.com/smaye81), [Buf](https://buf.build)\n- [Paul Sachs](https://github.com/paul-sachs), [Buf](https://buf.build)\n\n## Former\n\n- [Dimitri Mitropoulos](https://github.com/dimitropoulos)\n"
  },
  {
    "path": "README.md",
    "content": "<!-- markdownlint-disable-next-line MD041 MD033 -- 033: necessary for setting the width; 041: this is the style of bufbuild READMEs -->\n\n<img src=\"assets/connect-query@16x.png\" width=\"15%\" />\n\n<!-- omit in toc -->\n\n# Connect-Query\n\n[![License](https://img.shields.io/github/license/connectrpc/connect-query-es?color=blue)](./LICENSE) [![Build](https://github.com/connectrpc/connect-query-es/actions/workflows/ci.yaml/badge.svg?branch=main)](https://github.com/connectrpc/connect-query-es/actions/workflows/ci.yaml) [![NPM Version](https://img.shields.io/npm/v/@connectrpc/connect-query/latest?color=green&label=%40connectrpc%2Fconnect-query)](https://www.npmjs.com/package/@connectrpc/connect-query) [![NPM Version](https://img.shields.io/npm/v/@connectrpc/protoc-gen-connect-query/latest?color=green&label=%40connectrpc%2Fprotoc-gen-connect-query)](https://www.npmjs.com/package/@connectrpc/protoc-gen-connect-query)\n\nConnect-Query is an wrapper around [TanStack Query](https://tanstack.com/query) (react-query), written in TypeScript and thoroughly tested. It enables effortless communication with servers that speak the [Connect Protocol](https://connectrpc.com/docs/protocol).\n\n- [Quickstart](#quickstart)\n  - [Install](#install)\n  - [Usage](#usage)\n  - [Generated Code](#generated-code)\n- [Connect-Query API](#connect-query-api)\n  - [`TransportProvider`](#transportprovider)\n  - [`useTransport`](#usetransport)\n  - [`useQuery`](#usequery)\n  - [`useSuspenseQuery`](#usesuspensequery)\n  - [`useInfiniteQuery`](#useinfinitequery)\n  - [`useSuspenseInfiniteQuery`](#usesuspenseinfinitequery)\n  - [`useMutation`](#usemutation)\n  - [`createConnectQueryKey`](#createconnectquerykey)\n  - [`callUnaryMethod`](#callunarymethod)\n  - [`createProtobufSafeUpdater`](#createprotobufsafeupdater)\n  - [`createQueryOptions`](#createqueryoptions)\n  - [`createInfiniteQueryOptions`](#createinfinitequeryoptions)\n  - [`addStaticKeyToTransport`](#addstatickeytotransport)\n  - [`ConnectQueryKey`](#connectquerykey)\n  - [`QueryOptions`](#queryoptions)\n  - [`QueryOptionsWithSkipToken`](#queryoptionswithskiptoken)\n  - [`InfiniteQueryOptions`](#infinitequeryoptions)\n  - [`InfiniteQueryOptionsWithSkipToken`](#infinitequeryoptionswithskiptoken)\n\n## Quickstart\n\n### Install\n\n```sh\nnpm install @connectrpc/connect-query @connectrpc/connect-web\n```\n\n> [!TIP]\n>\n> If you are using something that doesn't automatically install peerDependencies (npm older than v7), you'll want to make sure you also have `@bufbuild/protobuf`, `@connectrpc/connect`, and `@tanstack/react-query` installed. `@connectrpc/connect-web` is required for defining\n> the transport to be used by the client.\n\n### Usage\n\nConnect-Query will immediately feel familiar to you if you've used TanStack Query. It provides a similar API, but instead takes a definition for your endpoint and returns a typesafe API for that endpoint.\n\nFirst, make sure you've configured your provider and query client:\n\n```tsx\nimport { createConnectTransport } from \"@connectrpc/connect-web\";\nimport { TransportProvider } from \"@connectrpc/connect-query\";\nimport { QueryClient, QueryClientProvider } from \"@tanstack/react-query\";\n\nconst finalTransport = createConnectTransport({\n  baseUrl: \"https://demo.connectrpc.com\",\n});\n\nconst queryClient = new QueryClient();\n\nfunction App() {\n  return (\n    <TransportProvider transport={finalTransport}>\n      <QueryClientProvider client={queryClient}>\n        <YourApp />\n      </QueryClientProvider>\n    </TransportProvider>\n  );\n}\n```\n\nWith configuration completed, you can now use the `useQuery` hook to make a request:\n\n```ts\nimport { useQuery } from '@connectrpc/connect-query';\nimport { say } from 'your-generated-code/eliza-ElizaService_connectquery';\n\nexport const Example: FC = () => {\n  const { data } = useQuery(say, { sentence: \"Hello\" });\n  return <div>{data}</div>;\n};\n```\n\n**_That's it!_**\n\nThe code generator does all the work of turning your Protobuf file into something you can easily import. TypeScript types all populate out-of-the-box. Your documentation is also converted to [TSDoc](https://tsdoc.org/).\n\nOne of the best features of this library is that once you write your schema in Protobuf form, the TypeScript types are generated and then inferred. You never again need to specify the types of your data since the library does it automatically.\n\n### Generated Code\n\nTo make a query, you need a schema for a remote procedure call (RPC). A typed schema can be generated with [`protoc-gen-es`](https://www.npmjs.com/package/@bufbuild/protoc-gen-es). It generates an export for every service:\n\n```ts\n/**\n * @generated from service connectrpc.eliza.v1.ElizaService\n */\nexport declare const ElizaService: GenService<{\n  /**\n   * Say is a unary RPC. Eliza responds to the prompt with a single sentence.\n   *\n   * @generated from rpc connectrpc.eliza.v1.ElizaService.Say\n   */\n  say: {\n    methodKind: \"unary\";\n    input: typeof SayRequestSchema;\n    output: typeof SayResponseSchema;\n  };\n}>;\n```\n\n[`protoc-gen-connect-query`](https://www.npmjs.com/package/@connectrpc/protoc-gen-connect-query) is an optional additional plugin that exports every RPC individually for convenience:\n\n```ts\nimport { ElizaService } from \"./eliza_pb\";\n\n/**\n * Say is a unary RPC. Eliza responds to the prompt with a single sentence.\n *\n * @generated from rpc connectrpc.eliza.v1.ElizaService.Say\n */\nexport const say: (typeof ElizaService)[\"method\"][\"say\"];\n```\n\nFor more information on code generation, see the [documentation for `protoc-gen-connect-query`](https://www.npmjs.com/package/@connectrpc/protoc-gen-connect-query) and the [documentation for `protoc-gen-es`](https://www.npmjs.com/package/@bufbuild/protoc-gen-es).\n\n## Connect-Query API\n\n### `TransportProvider`\n\n```ts\nconst TransportProvider: FC<\n  PropsWithChildren<{\n    transport: Transport;\n  }>\n>;\n```\n\n`TransportProvider` is the main mechanism by which Connect-Query keeps track of the `Transport` used by your application.\n\nBroadly speaking, \"transport\" joins two concepts:\n\n1. The protocol of communication. For this there are two options: the [Connect Protocol](https://connectrpc.com/docs/protocol/), or the [gRPC-Web Protocol](https://github.com/grpc/grpc/blob/master/doc/PROTOCOL-WEB.md).\n1. The protocol options. The primary important piece of information here is the `baseUrl`, but there are also other potentially critical options like request credentials, wire serialization options, or protocol-specific options like Connect's support for [HTTP GET](https://connectrpc.com/docs/web/get-requests-and-caching).\n\nWith these two pieces of information in hand, the transport provides the critical mechanism by which your app can make network requests.\n\nTo learn more about the two modes of transport, take a look at the Connect-Web documentation on [choosing a protocol](https://connectrpc.com/docs/web/choosing-a-protocol/).\n\nTo get started with Connect-Query, simply import a transport (either [`createConnectTransport`](https://github.com/connectrpc/connect-es/blob/main/packages/connect-web/src/connect-transport.ts) or [`createGrpcWebTransport`](https://github.com/connectrpc/connect-es/blob/main/packages/connect-web/src/grpc-web-transport.ts) from [`@connectrpc/connect-web`](https://www.npmjs.com/package/@connectrpc/connect-web)) and pass it to the provider.\n\nA common use case for the transport is to add headers to requests (like auth tokens, etc). You can do this with a custom [interceptor](https://connectrpc.com/docs/web/interceptors).\n\n```tsx\nimport { QueryClient, QueryClientProvider } from \"@tanstack/react-query\";\nimport { TransportProvider } from \"@connectrpc/connect-query\";\n\nconst queryClient = new QueryClient();\n\nexport const App = () => {\n  const transport = createConnectTransport({\n    baseUrl: \"<your baseUrl here>\",\n    interceptors: [\n      (next) => (request) => {\n        request.header.append(\"some-new-header\", \"some-value\");\n        // Add your headers here\n        return next(request);\n      },\n    ],\n  });\n  return (\n    <TransportProvider transport={transport}>\n      <QueryClientProvider client={queryClient}>\n        <YourApp />\n      </QueryClientProvider>\n    </TransportProvider>\n  );\n};\n```\n\nFor more details about what you can do with the transport, see the [Connect-Web documentation](https://connectrpc.com/docs/web/).\n\n### `useTransport`\n\n```ts\nconst useTransport: () => Transport;\n```\n\nUse this helper to get the default transport that's currently attached to the React context for the calling component.\n\n> [!TIP]\n>\n> All hooks accept a `transport` in the options. You can use the Transport from the context, or create one dynamically. If you create a Transport dynamically, make sure to memoize it, because it is taken into consideration when building query keys.\n\n### `useQuery`\n\n```ts\nfunction useQuery<\n  I extends DescMessage,\n  O extends DescMessage,\n  SelectOutData = MessageShape<O>,\n>(\n  schema: DescMethodUnary<I, O>,\n  input?: SkipToken | MessageInitShape<I>,\n  { transport, ...queryOptions }: UseQueryOptions<I, O, SelectOutData> = {},\n): UseQueryResult<SelectOutData, ConnectError>;\n```\n\nThe `useQuery` hook is the primary way to make a unary request. It's a wrapper around TanStack Query's [`useQuery`](https://tanstack.com/query/v5/docs/react/reference/useQuery) hook, but it's preconfigured with the correct `queryKey` and `queryFn` for the given method.\n\nAny additional `options` you pass to `useQuery` will be merged with the options that Connect-Query provides to @tanstack/react-query. This means that you can pass any additional options that TanStack Query supports.\n\n### `useSuspenseQuery`\n\nIdentical to useQuery but mapping to the `useSuspenseQuery` hook from [TanStack Query](https://tanstack.com/query/v5/docs/react/reference/useSuspenseQuery). This includes the benefits of narrowing the resulting data type (data will never be undefined).\n\n### `useInfiniteQuery`\n\n```ts\nfunction useInfiniteQuery<\n  I extends DescMessage,\n  O extends DescMessage,\n  ParamKey extends MessagePageParamKey<MessageInitShape<I>>,\n>(\n  schema: DescMethodUnary<I, O>,\n  input: SkipToken | MessageInitWithPageParam<MessageInitShape<I>, ParamKey>,\n  {\n    transport,\n    pageParamKey,\n    getNextPageParam,\n    ...queryOptions\n  }: UseInfiniteQueryOptions<I, O, ParamKey>,\n): UseInfiniteQueryResult<InfiniteData<MessageShape<O>>, ConnectError>;\n```\n\nThe `useInfiniteQuery` is a wrapper around TanStack Query's [`useInfiniteQuery`](https://tanstack.com/query/v5/docs/react/reference/useInfiniteQuery) hook, but it's preconfigured with the correct `queryKey` and `queryFn` for the given method.\n\nThere are some required options for `useInfiniteQuery`, primarily `pageParamKey` and `getNextPageParam`. These are required because Connect-Query doesn't know how to paginate your data. You must provide a mapping from the output of the previous page and getting the next page. `pageParamKey` supports root keys as strings (`\"page\"`) and nested keys as dot-separated strings (`\"query.page\"`). All other options passed to `useInfiniteQuery` will be merged with the options that Connect-Query provides to @tanstack/react-query. This means that you can pass any additional options that TanStack Query supports.\n\n### `useSuspenseInfiniteQuery`\n\nIdentical to useInfiniteQuery but mapping to the `useSuspenseInfiniteQuery` hook from [TanStack Query](https://tanstack.com/query/v5/docs/react/reference/useSuspenseInfiniteQuery). This includes the benefits of narrowing the resulting data type (data will never be undefined).\n\n### `useMutation`\n\n```ts\nfunction useMutation<I extends DescMessage, O extends DescMessage>(\n  schema: DescMethodUnary<I, O>,\n  { transport, ...queryOptions }: UseMutationOptions<I, O, Ctx> = {},\n): UseMutationResult<MessageShape<O>, ConnectError, PartialMessage<I>>;\n```\n\nThe `useMutation` is a wrapper around TanStack Query's [`useMutation`](https://tanstack.com/query/v5/docs/react/reference/useMutation) hook, but it's preconfigured with the correct `mutationFn` for the given method.\n\nAny additional `options` you pass to `useMutation` will be merged with the options that Connect-Query provides to @tanstack/react-query. This means that you can pass any additional options that TanStack Query supports.\n\n### `createConnectQueryKey`\n\nThis function is used under the hood of `useQuery` and other hooks to compute a [`queryKey`](https://tanstack.com/query/v4/docs/react/guides/query-keys) for TanStack Query. You can use it to create keys yourself to filter queries.\n\n`useQuery` creates a query key with the following parameters:\n\n1. The qualified name of the RPC.\n2. The transport being used.\n3. The request message.\n4. The cardinality of the RPC (either \"finite\" or \"infinite\").\n5. Adds a DataTag which brands the key with the associated data type of the response.\n\nThe DataTag type allows @tanstack/react-query functions to properly infer the type of the data returned by the query. This is useful for things like `QueryClient.setQueryData` and `QueryClient.getQueryData`.\n\nTo create the same key manually, you simply provide the same parameters:\n\n```ts\nimport { createConnectQueryKey, useTransport } from \"@connectrpc/connect-query\";\nimport { ElizaService } from \"./gen/eliza_pb\";\n\nconst myTransport = useTransport();\nconst queryKey = createConnectQueryKey({\n  schema: ElizaService.method.say,\n  transport: myTransport,\n  // You can provide a partial message here.\n  input: { sentence: \"hello\" },\n  // This defines what kind of request it is (either for an infinite or finite query).\n  cardinality: \"finite\",\n});\n\n// queryKey:\n[\n  \"connect-query\",\n  {\n    transport: \"t1\",\n    serviceName: \"connectrpc.eliza.v1.ElizaService\",\n    methodName: \"Say\",\n    input: { sentence: \"hello\" },\n    cardinality: \"finite\",\n  },\n];\n```\n\nYou can create a partial key that matches all RPCs of a service:\n\n```ts\nimport { createConnectQueryKey } from \"@connectrpc/connect-query\";\nimport { ElizaService } from \"./gen/eliza_pb\";\n\nconst queryKey = createConnectQueryKey({\n  schema: ElizaService,\n  cardinality: \"finite\",\n});\n\n// queryKey:\n[\n  \"connect-query\",\n  {\n    serviceName: \"connectrpc.eliza.v1.ElizaService\",\n    cardinality: \"finite\",\n  },\n];\n```\n\nInfinite queries have distinct keys. To create a key for an infinite query, use the parameter `cardinality`:\n\n```ts\nimport { createConnectQueryKey } from \"@connectrpc/connect-query\";\nimport { ListService } from \"./gen/list_pb\";\n\n// The hook useInfiniteQuery() creates a query key with cardinality: \"infinite\",\n// and passes on the pageParamKey.\nconst queryKey = createConnectQueryKey({\n  schema: ListService.method.list,\n  cardinality: \"infinite\",\n  pageParamKey: \"page\",\n  input: { preview: true },\n});\n```\n\n### `callUnaryMethod`\n\n```ts\nfunction callUnaryMethod<I extends DescMessage, O extends DescMessage>(\n  transport: Transport,\n  schema: DescMethodUnary<I, O>,\n  input: MessageInitShape<I> | undefined,\n  options?: {\n    signal?: AbortSignal;\n  },\n): Promise<O>;\n```\n\nThis API allows you to directly call the method using the provided transport. Use this if you need to manually call a method outside of the context of a React component, or need to call it where you can't use hooks.\n\n### `createProtobufSafeUpdater` (deprecated)\n\nCreates a typesafe updater that can be used to update data in a query cache. Used in combination with a queryClient.\n\n```ts\nimport { createProtobufSafeUpdater, useTransport } from '@connectrpc/connect-query';\nimport { useQueryClient } from \"@tanstack/react-query\";\n\n...\n\nconst queryClient = useQueryClient();\nconst transport = useTransport();\nqueryClient.setQueryData(\n  createConnectQueryKey({\n    schema: example,\n    transport,\n    input: {},\n    cardinality: \"finite\",\n  }),\n  createProtobufSafeUpdater(example, (prev) => {\n    if (prev === undefined) {\n      return undefined;\n    }\n    return {\n      ...prev,\n      completed: true,\n    };\n  })\n);\n\n```\n\n** Note: This API is deprecated and will be removed in a future version. `ConnectQueryKey` now contains type information to make it safer to use `setQueryData` directly. **\n\n### `createQueryOptions`\n\n```ts\nfunction createQueryOptions<I extends DescMessage, O extends DescMessage>(\n  schema: DescMethodUnary<I, O>,\n  input: SkipToken | PartialMessage<I> | undefined,\n  {\n    transport,\n  }: {\n    transport: Transport;\n  },\n): {\n  queryKey: ConnectQueryKey;\n  queryFn: QueryFunction<MessageShape<O>, ConnectQueryKey> | SkipToken;\n  structuralSharing: (oldData: unknown, newData: unknown) => unknown;\n};\n```\n\nA functional version of the options that can be passed to the `useQuery` hook from `@tanstack/react-query`. When called, it will return the appropriate `queryKey`, `queryFn`, and `structuralSharing` flag. This is useful when interacting with `useQueries` API or queryClient methods (like [ensureQueryData](https://tanstack.com/query/latest/docs/reference/QueryClient#queryclientensurequerydata), etc).\n\nAn example of how to use this function with `useQueries`:\n\n```ts\nimport { useQueries } from \"@tanstack/react-query\";\nimport { createQueryOptions, useTransport } from \"@connectrpc/connect-query\";\nimport { example } from \"your-generated-code/example-ExampleService_connectquery\";\n\nconst MyComponent = () => {\n  const transport = useTransport();\n  const [query1, query2] = useQueries([\n    createQueryOptions(example, { sentence: \"First query\" }, { transport }),\n    createQueryOptions(example, { sentence: \"Second query\" }, { transport }),\n  ]);\n  ...\n};\n```\n\n### `createInfiniteQueryOptions`\n\n```ts\nfunction createInfiniteQueryOptions<\n  I extends DescMessage,\n  O extends DescMessage,\n  ParamKey extends MessagePageParamKey<MessageInitShape<I>>,\n>(\n  schema: DescMethodUnary<I, O>,\n  input: SkipToken | MessageInitWithPageParam<MessageInitShape<I>, ParamKey>,\n  {\n    transport,\n    getNextPageParam,\n    pageParamKey,\n  }: ConnectInfiniteQueryOptions<I, O, ParamKey>,\n): {\n  getNextPageParam: ConnectInfiniteQueryOptions<\n    I,\n    O,\n    ParamKey\n  >[\"getNextPageParam\"];\n  queryKey: ConnectInfiniteQueryKey<I>;\n  queryFn:\n    | QueryFunction<\n        MessageShape<O>,\n        ConnectInfiniteQueryKey<I>,\n        MessageInitShape<I>[ParamKey]\n      >\n    | SkipToken;\n  structuralSharing: (oldData: unknown, newData: unknown) => unknown;\n  initialPageParam: PartialMessage<I>[ParamKey];\n};\n```\n\nA functional version of the options that can be passed to the `useInfiniteQuery` hook from `@tanstack/react-query`.When called, it will return the appropriate `queryKey`, `queryFn`, and `structuralSharing` flags, as well as a few other parameters required for `useInfiniteQuery`. This is useful when interacting with some queryClient methods (like [ensureQueryData](https://tanstack.com/query/latest/docs/reference/QueryClient#queryclientensurequerydata), etc).\n\n### `addStaticKeyToTransport`\n\nTransports are taken into consideration when building query keys for associated queries. This can cause issues with SSR since the transport on the server is not the same transport that gets executed on the client (cannot be tracked by reference). To bypass this, you can use this method to add an explicit key to the transport that will be used in the query key. For example:\n\n```ts\nimport { addStaticKeyToTransport } from \"@connectrpc/connect-query\";\nimport { createConnectTransport } from \"@connectrpc/connect-web\";\n\nconst transport = addStaticKeyToTransport(\n  createConnectTransport({\n    baseUrl: \"https://demo.connectrpc.com\",\n  }),\n  \"demo\",\n);\n```\n\n### `ConnectQueryKey`\n\n```ts\ntype ConnectQueryKey = [\n  /**\n   * To distinguish Connect query keys from other query keys, they always start with the string \"connect-query\".\n   */\n  \"connect-query\",\n  {\n    /**\n     * A key for a Transport reference, created with createTransportKey().\n     */\n    transport?: string;\n    /**\n     * The name of the service, e.g. connectrpc.eliza.v1.ElizaService\n     */\n    serviceName: string;\n    /**\n     * The name of the method, e.g. Say.\n     */\n    methodName?: string;\n    /**\n     * A key for the request message, created with createMessageKey(),\n     * or \"skipped\".\n     */\n    input?: Record<string, unknown> | \"skipped\";\n    /**\n     * Whether this is an infinite query, or a regular one.\n     */\n    cardinality?: \"infinite\" | \"finite\";\n  },\n];\n```\n\nTanStack Query manages query caching for you based on query keys. [`QueryKey`s](https://tanstack.com/query/v4/docs/react/guides/query-keys) in TanStack Query are arrays with arbitrary JSON-serializable data - typically handwritten for each endpoint. In Connect-Query, query keys are more structured, since queries are always tied to a service, RPC, input message, and transport. For example, a query key might look like this:\n\n```ts\n[\n  \"connect-query\",\n  {\n    transport: \"t1\",\n    serviceName: \"connectrpc.eliza.v1.ElizaService\",\n    methodName: \"Say\",\n    input: {\n      sentence: \"hello there\",\n    },\n    cardinality: \"finite\",\n  },\n];\n```\n\nThe factory [`createConnectQueryKey`](#createconnectquerykey) makes it easy to create a `ConnectQueryKey`, including partial keys for query filters.\n\n### `QueryOptions`\n\nReturn type of `createQueryOptions` assuming SkipToken was not provided.\n\n```ts\ninterface QueryOptions<I extends DescMessage, O extends DescMessage> {\n  queryKey: ConnectQueryKey<O>;\n  queryFn: QueryFunction<MessageShape<O>, ConnectQueryKey<O>, MessageShape<I>>;\n  structuralSharing: (oldData: unknown, newData: unknown) => unknown;\n}\n```\n\n### `QueryOptionsWithSkipToken`\n\nReturn type of `createQueryOptions` when SkipToken is provided.\n\n```ts\ninterface QueryOptionsWithSkipToken<\n  I extends DescMessage,\n  O extends DescMessage,\n> extends Omit<QueryOptions<I, O>, \"queryFn\"> {\n  queryFn: SkipToken;\n}\n```\n\n### `InfiniteQueryOptions`\n\nReturn type of `createInfiniteQueryOptions` assuming SkipToken was not provided.\n\n```ts\ninterface InfiniteQueryOptions<\n  I extends DescMessage,\n  O extends DescMessage,\n  ParamKey extends keyof MessageInitShape<I>,\n> {\n  getNextPageParam: ConnectInfiniteQueryOptions<\n    I,\n    O,\n    ParamKey\n  >[\"getNextPageParam\"];\n  queryKey: ConnectQueryKey<O>;\n  queryFn: QueryFunction<\n    MessageShape<O>,\n    ConnectQueryKey<O>,\n    MessageInitShape<I>[ParamKey]\n  >;\n  structuralSharing: (oldData: unknown, newData: unknown) => unknown;\n  initialPageParam: MessageInitShape<I>[ParamKey];\n}\n```\n\n### `InfiniteQueryOptionsWithSkipToken`\n\nReturn type of `createInfiniteQueryOptions` when SkipToken is provided.\n\n```ts\ninterface InfiniteQueryOptionsWithSkipToken<\n  I extends DescMessage,\n  O extends DescMessage,\n  ParamKey extends keyof MessageInitShape<I>,\n> extends Omit<InfiniteQueryOptions<I, O, ParamKey>, \"queryFn\"> {\n  queryFn: SkipToken;\n}\n```\n\n## Testing\n\nConnect-query (along with all other javascript based connect packages) can be tested with the `createRouterTransport` function from `@connectrpc/connect`. This function allows you to create a transport that can be used to test your application without needing to make any network requests. We also have a dedicated package, [@connectrpc/connect-playwright](https://github.com/connectrpc/connect-playwright-es) for testing within [playwright](https://playwright.dev/).\n\nFor playwright, you can see a sample test [here](https://github.com/connectrpc/connect-playwright-es/blob/main/packages/connect-playwright-example/tests/simple.spec.ts).\n\n## Frequently Asked Questions\n\n### How do I pass other TanStack Query options?\n\nEach function that interacts with TanStack Query also provides for options that can be passed through.\n\n```ts\nimport { useQuery } from '@connectrpc/connect-query';\nimport { example } from 'your-generated-code/example-ExampleService_connectquery';\n\nexport const Example: FC = () => {\n  const { data } = useQuery(example, undefined, {\n    // These are typesafe options that are passed to underlying TanStack Query.\n    refetchInterval: 1000,\n  });\n  return <div>{data}</div>;\n};\n```\n\n### What is Connect-Query's relationship to Connect-Web and Protobuf-ES?\n\nHere is a high-level overview of how Connect-Query fits in with Connect-Web and Protobuf-ES:\n\n<details>\n<summary>Expand to see a detailed dependency graph</summary>\n\n<!-- markdownlint-disable-next-line MD033 -- 033: necessary for setting the width; -->\n\n<img\n  alt=\"connect-query_dependency_graph\"\n  src=\"./assets/connect-query_dependency_graph.png\"\n  width=\"75%\"\n/>\n\n</details>\n\nYour Protobuf files serve as the primary input to the code generators `protoc-gen-connect-query` and `protoc-gen-es`. Both of these code generators also rely on primitives provided by Protobuf-ES. The Buf CLI produces the generated output. The final generated code uses `Transport` from Connect-Web and generates a final Connect-Query API.\n\n### What is `Transport`\n\n`Transport` is a regular JavaScript object with two methods, `unary` and `stream`. See the definition in the Connect-Web codebase [here](https://github.com/connectrpc/connect-es/blob/main/packages/connect/src/transport.ts). `Transport` defines the mechanism by which the browser can call a gRPC-web or Connect backend. Read more about Transport on the [connect docs](https://connectrpc.com/docs/web/choosing-a-protocol).\n\n### What if I already use Connect-Web?\n\nYou can use Connect-Web and Connect-Query together if you like!\n\n### What if I use gRPC-web?\n\nConnect-Query also supports gRPC-web! All you need to do is make sure you call `createGrpcWebTransport` instead of `createConnectTransport`.\n\nThat said, we encourage you to check out the [Connect protocol](https://connectrpc.com/docs/protocol/), a simple, POST-only protocol that works over HTTP/1.1 or HTTP/2. It supports server-streaming methods just like gRPC-Web, but is easy to debug in the network inspector.\n\n### What if I have a custom `Transport`?\n\nIf the `Transport` attached to React Context via the `TransportProvider` isn't working for you, then you can override transport at every level. For example, you can pass a custom transport directly to the lowest-level API like `useQuery` or `callUnaryMethod`.\n\n### Does this only work with React?\n\nConnect-Query does require React, but the core (`createConnectQueryKey` and `callUnaryMethod`) is not React specific so splitting off a `connect-solid-query` is possible.\n\n### How do I do Prefetching?\n\nWhen you might not have access to React context, you can use `createQueryOptions` and provide a transport directly. For example:\n\n```ts\nimport { say } from \"./gen/eliza-ElizaService_connectquery\";\n\nfunction prefetch() {\n  return queryClient.prefetchQuery(\n    createQueryOptions(say, { sentence: \"Hello\" }, { transport: myTransport }),\n  );\n}\n```\n\n> [!TIP]\n>\n> Transports are taken into consideration when building query keys. If you want to prefetch queries on the server, and hydrate them in the client, make sure to use the same transport key on both sides with [`addStaticKeyToTransport`](#addstatickeytotransport).\n\n### What about Streaming?\n\nConnect-Query currently only supports Unary RPC methods, which use a simple request/response style of communication similar to GET or POST requests in REST. This is because it aligns most closely with TanStack Query's paradigms. However, we understand that there may be use cases for Server Streaming, Client Streaming, and Bidirectional Streaming, and we're eager to hear about them.\n\nAt Buf, we strive to build software that solves real-world problems, so we'd love to learn more about your specific use case. If you can provide a small, reproducible example, it will help us shape the development of a future API for streaming with Connect-Query.\n\nTo get started, we invite you to open a pull request with an example project in the examples directory of the Connect-Query repository. If you're not quite sure how to implement your idea, don't worry - we want to see how you envision it working. If you already have an isolated example, you may also provide a simple CodeSandbox or Git repository.\n\nIf you're not yet at the point of creating an example project, feel free to open an issue in the repository and describe your use case. We'll follow up with questions to better understand your needs.\n\nYour input and ideas are crucial in shaping the future development of Connect-Query. We appreciate your input and look forward to hearing from you.\n\n## Legal\n\nOffered under the [Apache 2 license](/LICENSE).\n"
  },
  {
    "path": "SECURITY.md",
    "content": "# Security Policy\n\nThis project follows the [Connect security policy and reporting\nprocess](https://connectrpc.com/docs/governance/security).\n"
  },
  {
    "path": "assets/connect-query.ai",
    "content": "%PDF-1.6\r%\r\n1 0 obj\r<</Metadata 2 0 R/OCProperties<</D<</ON[18 0 R]/Order 19 0 R/RBGroups[]>>/OCGs[18 0 R]>>/Pages 3 0 R/Type/Catalog>>\rendobj\r2 0 obj\r<</Length 31167/Subtype/XML/Type/Metadata>>stream\r\n<?xpacket begin=\"﻿\" id=\"W5M0MpCehiHzreSzNTczkc9d\"?>\n<x:xmpmeta xmlns:x=\"adobe:ns:meta/\" x:xmptk=\"Adobe XMP Core 7.2-c000 79.1b65a79, 2022/06/13-17:46:14        \">\n   <rdf:RDF xmlns:rdf=\"http://www.w3.org/1999/02/22-rdf-syntax-ns#\">\n      <rdf:Description rdf:about=\"\"\n            xmlns:xmp=\"http://ns.adobe.com/xap/1.0/\"\n            xmlns:xmpGImg=\"http://ns.adobe.com/xap/1.0/g/img/\"\n            xmlns:xmpTPg=\"http://ns.adobe.com/xap/1.0/t/pg/\"\n            xmlns:stDim=\"http://ns.adobe.com/xap/1.0/sType/Dimensions#\"\n            xmlns:xmpG=\"http://ns.adobe.com/xap/1.0/g/\"\n            xmlns:dc=\"http://purl.org/dc/elements/1.1/\"\n            xmlns:xmpMM=\"http://ns.adobe.com/xap/1.0/mm/\"\n            xmlns:stRef=\"http://ns.adobe.com/xap/1.0/sType/ResourceRef#\"\n            xmlns:stEvt=\"http://ns.adobe.com/xap/1.0/sType/ResourceEvent#\"\n            xmlns:illustrator=\"http://ns.adobe.com/illustrator/1.0/\"\n            xmlns:pdf=\"http://ns.adobe.com/pdf/1.3/\">\n         <xmp:CreatorTool>Adobe Illustrator 26.5 (Windows)</xmp:CreatorTool>\n         <xmp:CreateDate>2022-11-15T17:46:08-04:00</xmp:CreateDate>\n         <xmp:MetadataDate>2022-11-15T17:46:08-05:00</xmp:MetadataDate>\n         <xmp:ModifyDate>2022-11-15T17:46:08-05:00</xmp:ModifyDate>\n         <xmp:Thumbnails>\n            <rdf:Alt>\n               <rdf:li rdf:parseType=\"Resource\">\n                  <xmpGImg:width>256</xmpGImg:width>\n                  <xmpGImg:height>232</xmpGImg:height>\n                  <xmpGImg:format>JPEG</xmpGImg:format>\n                  <xmpGImg:image>/9j/4AAQSkZJRgABAgEASABIAAD/7QAsUGhvdG9zaG9wIDMuMAA4QklNA+0AAAAAABAASAAAAAEA&#xA;AQBIAAAAAQAB/+4ADkFkb2JlAGTAAAAAAf/bAIQABgQEBAUEBgUFBgkGBQYJCwgGBggLDAoKCwoK&#xA;DBAMDAwMDAwQDA4PEA8ODBMTFBQTExwbGxscHx8fHx8fHx8fHwEHBwcNDA0YEBAYGhURFRofHx8f&#xA;Hx8fHx8fHx8fHx8fHx8fHx8fHx8fHx8fHx8fHx8fHx8fHx8fHx8fHx8fHx8f/8AAEQgA6AEAAwER&#xA;AAIRAQMRAf/EAaIAAAAHAQEBAQEAAAAAAAAAAAQFAwIGAQAHCAkKCwEAAgIDAQEBAQEAAAAAAAAA&#xA;AQACAwQFBgcICQoLEAACAQMDAgQCBgcDBAIGAnMBAgMRBAAFIRIxQVEGE2EicYEUMpGhBxWxQiPB&#xA;UtHhMxZi8CRygvElQzRTkqKyY3PCNUQnk6OzNhdUZHTD0uIIJoMJChgZhJRFRqS0VtNVKBry4/PE&#xA;1OT0ZXWFlaW1xdXl9WZ2hpamtsbW5vY3R1dnd4eXp7fH1+f3OEhYaHiImKi4yNjo+Ck5SVlpeYmZ&#xA;qbnJ2en5KjpKWmp6ipqqusra6voRAAICAQIDBQUEBQYECAMDbQEAAhEDBCESMUEFURNhIgZxgZEy&#xA;obHwFMHR4SNCFVJicvEzJDRDghaSUyWiY7LCB3PSNeJEgxdUkwgJChgZJjZFGidkdFU38qOzwygp&#xA;0+PzhJSktMTU5PRldYWVpbXF1eX1RlZmdoaWprbG1ub2R1dnd4eXp7fH1+f3OEhYaHiImKi4yNjo&#xA;+DlJWWl5iZmpucnZ6fkqOkpaanqKmqq6ytrq+v/aAAwDAQACEQMRAD8A9U4q7FXYq7FXYq7FXYq8&#xA;4/Nv87NB/L+3W1CDUNfnTlb6crcQinYSTsK8V8B1b8cuxYTP3NGbOIe98rebfzm/MfzRK5v9Zmgt&#xA;XJpY2TG2gAP7PGMhnH+uWOZ8MMY9HXzzSlzLCmZnYsxLMxqzHcknuctak60Tzt5w0J1bR9avLEJ0&#xA;jhnkWMgdjHXgw9iMjKETzDOM5DkXrnkv/nLDzTp7R2/mmzj1i16Ndwhbe6Ar1IUek9B24r88x56U&#xA;Hls5ENWRz3fRPkn8yfJ/nS09fQb9ZpUFZ7KT93cxf68R3p/lCq+BzCnjlHm5sMsZcmTZBsdirsVd&#xA;irsVdirz38wvzy8jeSvUtrm4OoawtR+jLMq8isO0z14Rf7I8vBTl2PBKXuacmeMfe+fPN3/OUH5i&#xA;ay7xaS0Wg2R2VLdRLOV/yp5Ad/dFXMyGmiOe7hT1Ujy2eYat5m8x6w5fVdUu7926m5nkl96fGxy8&#xA;RA5BoMieZS9JHjcPGxR13VlNCPkRhYs28p/nT+ZHliZGstZnubVKVsb1muYCo/ZCyElB/qFTlU8M&#xA;ZdG2GeUer6n/ACk/OzQfzAt2tSg0/X4E5XGnM3IOo2MkDGnJfEdV/HMDLhMPc7DDnE/e9Hylvdir&#xA;sVdirsVdirsVdirsVdirsVdirsVYt+Znnq08keTr3Xp1Ek0YEVjbk09W5k2jT5Ddm/yQcsxQ4pU1&#xA;5cnBG3wdrGr6jrGqXWqalO1zf3kjS3E79WZj+AHQAbAbDNqAAKDqCSTZTTy35OvtZX12b6vZg09Z&#xA;hUsR1CLtX55harXRxbc5PR9iezWbXDjJ4MXf3+4fpZbH+W+gqgDyXDt3bmo/ALmsPauXuD2UPYnR&#xA;gbnIT7x+pDXn5ZWDKTZ3csTdhKFkH4cDlkO1pfxAFxtT7C4SP3WSUT/SqX3UxbWPJ+t6YDJJF61u&#xA;Os8NWUD/AChTkPpGbHBrseTYGj5vIdpezer0g4pR4ofzo7j49R93mlunalqGmXsN9p1zJaXsDc4b&#xA;iFikiN4hlocyyAebogSNw+kvyo/5ygiuGh0fz0VhlNEh11BxRj0H1lF2T/XXbxA65hZdL1i52HVd&#xA;JPomKWKaJJoXWSKRQ8ciEMrKwqGUjYgjMNzV2KuxVB6vrGl6Np0+papdR2dhbLzmuJTxVR/EnoAN&#xA;zhAJNBBkALL5Z/Nf/nJfWNcabSfKDSaXo5qkmofZu7gdPhI/uUPt8XuOmZ+LTAby5uvzaonaPJ4Y&#xA;zMzFmJLE1JO5JOZTiI7StC1XVJONnAzqDRpT8KL82O2U5tRDGPUXY9n9k6jVmsUSR38gPj+Cy+w/&#xA;LJOIbULwlu8cAAA/2bg/8RzVZO1j/CPm9ppPYUVebJv3R/Wf1I9/y30AqQslwp7MHU/rXKR2rl8n&#xA;ZS9idERscg+I/wCJYr5j8lXukIbmJ/rNkPtSAUZK/wAy77e4zZaXXxymjtJ5Dtv2Xy6MeJE8eLv6&#xA;j3j9P3JRo+r6jo+qWuqabO1tf2ciy286dVZT+IPQg7EbHM4gEUXmASDYfef5a+d7Xzr5OsNehCxz&#xA;TKY72BTX0riPaRPlX4l/ySM1WSHDKnb4p8UbZPlbY7FXYq7FXYq7FXYq7FXYq7FXYq7FXyp/zlt5&#xA;re78z6b5aif/AEfTIPrNwo73Fx0B/wBWJQR/rHM/SQ2t1+snZp4ho+ntqOp21ku3rOFYjqFG7H6F&#xA;By7Pl8OBl3J7N0Z1OohiH8R+zr9j2iCCKCFIIVCRRqFRB0AAoBnJSkZGzzfdsWKOOAhEVGIoKmRb&#xA;HYq7FWL+YfI2n6iGnswtpeHeoFI3P+Uo6fMfjmx0vaMse0vVH7Xk+2fZTDqbnirHl/2J94/SPtec&#xA;ahp15p9y1tdxGKVex6EeKnuM3+LLGYuJsPl2s0WXTZDjyx4ZD8WO8PSPyh/PXXfI08en3pfUfLLt&#xA;+8siayQVO72xY7eJQ/CfY75DNgEt+rHDnMNuj7C8t+ZdE8yaRBq+i3aXlhcCqSJ1B7o6ndWXup3G&#xA;a6UTE0XZRkJCwhfOfnXy/wCTtDl1nW7j0bZDxjjX4pZZD9mOJNuTH8Op2wwgZGgicxEWXxd+aH5t&#xA;eY/P+p+peMbXSYGJsdKjascfbk529SQjqx+igzZYsQgPN1eXMZnyYTHHJLIscal5HNFRRUknsAMs&#xA;JAFlhCEpyEYiyejO/Lv5eii3Osbnqtmp/wCJsP1DNNqu0+mP5/qfQuxfY3lk1X+k/wCKP6B8+jOI&#xA;YYYYlihRY40FFRQAAPYDNPKRJsvf48UccRGIEYjoF+RbHYqsljjljaORQ8bgq6ncEHYg4QSDYYTh&#xA;GcTGQsHYvHPMOknStXns+sanlCfGNt1+7pnWaXN4mMSfD+2ezzpNTLF/CN4/1Ty/U91/5xC8yyR6&#xA;trflqR6w3EK6hbqegkhYRS093WRP+ByrVx2BaNHLch9P5gue7FXYq7FXYq7FXYq7FXYq7FXYq7FX&#xA;wX+cmqNqf5peZ7liW4X8tsCTX4bU/V1+ikW2bbCKgHUZjcyh/wAuLcSa88pH9xA7L/rMVX9ROYPa&#xA;sqxV3l6v2JwiWsMj/DAn5kD7iXp2c6+ruxV2KuxV2KpfrOiWGr2pt7pKkVMUo+2hPdT/AAy/BqJY&#xA;pXF1vafZeHWY+DIPceo9343eVa9oF9o136NwOUTVME4+y6j9R8RnS6bUxyxsc+58f7W7Iy6HJwz+&#xA;k/TLof294T38tfzP8xeQtZW906Qy2MrKNQ01yfSmQEV/1XA+y46e4qMsyYhMbuvxZTA7If8AML8x&#xA;PMPnrXX1PVpSIlJWysUJ9G3jP7KA9zQcm6t9wBx4xEUEZMhmbKRaZpd7qV0ttZxmSRtyf2VH8zHs&#xA;MGXNHHG5FyNDoMuqyDHiFy+weZ7g9R8ueVLHRow+016w/eXBHSvUIOw/XnN6rWyymuUe59b7E9n8&#xA;Ohjf1ZTzl+gdw+9PMw3oHYq7FXYq7FWAfmdaATWN2Bu6vE5/1SGX/iRzedkT2lH4vnHt3pwJYso6&#xA;gxPw3H3lMv8AnHK/e0/N/RAPsXQuYJAOtGt5CvcftqubLUD0F4bTGph9t5q3auxV2KuxV2KuxV2K&#xA;uxV2KuxV2KuxV+d/m6Zp/NetTMAGlv7lyB0BaZjm4hyDpZ8yn35YgfX709/SXf8A2Wavtf6Y+97n&#xA;2EH77J/VH3vRM0L6Y7FXYq7FXYq7FUJqemWepWb2l2nON+h/aVuzKexGW4c0scuKLh6/QYtViOPI&#xA;LifmD3jzeTeYPL95o14YZhzhepgnA+F1/gR3GdNptTHLGxz6h8b7Y7Hy6HLwy3ifpl0I/X3hK8yX&#xA;UPWPI9vp8fl+3ktQpklFblx9oyA7hv8AV7ZzPaEpHKRLpyfY/ZXDhjooSx1cvqPXi8/d08veyDMF&#xA;6R2KuxV2KuxV2KsO/M0D9FWhpuJ6A/NGzbdk/Wfc8P7dD/B8Z/p/oKA/JIkfmv5Zp/y2L/xFs3Ob&#xA;6C+a4PrD7uzVO3dirsVdirsVdirsVdirsVdirsVdir89vPlv9W88+YrfiF9HU7yPivQcLhxQfdm4&#xA;x/SPc6bIPUfemf5ZyU1e6jr9q35U/wBV1H/G2aztYfuwfN7P2Gn/AITOPfj+6Q/W9IzQPqLsVdir&#xA;sVdirsVdiqD1XSrTVLJ7S6Wsb7qw+0rDoynxGW4c0scuKLhdoaDFq8RxZBsfmD3h5FrWjXekXzWt&#xA;wK94pB9l17EfxzqdPnjljxB8W7U7MyaPMcc/gehHejvKnmSTRr2khLWMxAuI+tPB1HiPxynW6UZY&#xA;7fUOTn+z3bctDl33xS+of74eY+0fB6xFLHLEksTB43AZHU1BB3BGcwQQaL7JjyRnESibidwV+Bm7&#xA;FXYq7FXYqwz8zXA02zTu0xYfQhH8c23ZI9ZPk8N7dS/cYx/T/R+1S/IK2+s/m95bj48uM0stK0/u&#xA;reSSv0ca5uc59BfN9OPWH3Nmqds7FXYq7FXYq7FXYq7FXYq7FXYq7FXwr+eumtp/5teZISKCW5Fy&#xA;vuLmNZq/8lM2uA3AOpziplJ/y/mEfmWJP9/RyJ9y8/8AjXMXtON4T5EPRex+Xh18R/OjIfZf6Hqm&#xA;c0+vuxV2KuxV2KuxV2KuxVK/MGg22s2DW8vwyrVoJqbo39D3GZOm1JxSscurqe2OyceuwmEtpD6Z&#xA;dx/V3vIr6yubG7ktblOE0Roy/qI9jnUY8gnESHIvi2q0uTT5DjyCpRZb5C8z/V5V0m7f9xIf9Fcn&#xA;7Ln9j5Menv8APNZ2lpOIccefV7P2R7d8OQ02U+iX0HuPd7j08/e9EzQvpjsVdirsVdirz/8AM+es&#xA;9hbj9lZJCP8AWIA/4ic3nZEdpH3Pm/t5mueKHcJH50P0Mk/5xc083X5rwT0r9Qs7m4J8OSiCvQ/7&#xA;+zYao+h4nSj1vsrNa7N2KuxV2KuxV2KuxV2KuxV2KuxV2Kvkf/nLPRTafmBZamq0i1KwTk3jLA7I&#xA;3/CFM2Gkl6adbq4+q3kfly5+ra9YTE0AmRWPgrnifwOT1UOLFIeTldi5/C1mKX9MfI7H73s2ck+5&#xA;uxV2KrJJY4xykcIvixAH44QCeTCc4xFyNIWXW9Gi/vL+3QjsZUB29q5aNPkPKJ+Th5O1NLD6suMf&#xA;50f1oWTzZ5cjryv4jT+Ulv8AiIOWDRZj/CXEn7Q6GPPLH7/uUW88eVlNDfCvtHKf1Jkx2fm/m/aP&#xA;1tB9quzx/lf9jP8A4lS/x75Y/wCWlv8AkW/9Ml/Jubu+0NX+i7s/+ef9LL9Tv8feWf8Alob/AJFv&#xA;/TH+Tc3d9q/6Luz/AOef9LL9TAvNes2+rau11boUiCLGpbZm41+Ij6c3eiwHFj4TzfOvaHtKGs1J&#xA;yQFRoDzNdfx0SbpuMynRvUvJPmT9KWf1W4at9bAcierp0D/Psc5vtDSeHLiH0l9d9l+2/wA3i8OZ&#xA;/fQ/2Q7/ANf7WTZr3qnYq7FXYq8q8/XYn8yTKDUW6JED9HI/i5zpezYcOEee74/7X6jxNdIfzAI/&#xA;p+8vZP8AnD3SueseY9WK/wC89vBaI3/Gd2kYD/kQtcnqzsA6XRjcl9P5gue7FXYq7FXYq7FXYq7F&#xA;XYq7FXYq7FXg3/OXOkwXPlHSNT5r9a0+8aMRkgMYblKOQOpo8SZl6Q7kOHrB6QXymCVIINCNwffM&#xA;9wASDYZav5laytuqehA0wFGlYNv78QRvmrPZWO7s09nH241QgBwwMu/f7rCBuPPfmWatLkQqf2Y0&#xA;UfiQT+OXR7Owjpbr83tZr58p8PuiP2lLp9d1qevq307A/s+owH3A0zIjp8ceUR8nV5e1tXk+rLM/&#xA;5x+5As7uasxY+JNTlwFOBKRJs7tYodiqZaR5b1/WGK6Xp1xeUNGaGNmVf9ZgOI+k4QCWEskY8zTK&#xA;bX8kvzFnALackAPeWeEfgrMcl4ZaDrMY6r7j8jvzFiBKWMU9BWkdxEPo+Nkx8MqNZj72Nax5O806&#xA;OGbU9KubaJeszRkxf8jFqn45ExIboZYy5FJsDYitN1C5069ivLc0kiNadiO6n2IyvLiGSJierl6H&#xA;WT02WOWH1RP4Hxex6VqdvqdhFeW5+CUbqeqsOqn3BzlM2I45GJfb+z9dDVYY5YcpfYeo+CLypzXY&#xA;qtd1RS7GiqCWJ7AYQLYykIizyDxHULpru+uLpus8jSfLkSaZ2GKHDER7g+B6zUHNmnkP8cifmX1h&#xA;/wA4m2FtbeQLy4E0b3d9fSSPErqXSKNFiTmoJK/ErnfscwtWfU5OkHpe3ZiuU7FXYq7FXYq7FXYq&#xA;7FXYqtlliijaWV1jjQFndiAoA3JJPTFXlXnT/nJT8uvLpkt7GZtev0qPSsaGEMP5rhvgp7pyzIhp&#xA;pHyceepjHzeF+bv+cmvzH1z1IdOlj0GyaoCWYrOV/wAqd6tX3QLmVDTRHPdxJ6qR5bPLL6/v7+5e&#xA;6v7mW7upN5J53aSRvmzkk5kAU45N81OC3uJ34QRPK/8AKilj9wyMpCPM0zxYZ5DUImR8hacWnkvz&#xA;Jc7izMS/zSlU/Anl+GYs9fhj1v3O70/sxr8vLHwj+lQ+w7/Ym9t+WWotT6zeRRf8Yw0h/HhmLPta&#xA;A5An8fF3WD2Fzn+8yRj7gZf8SiL38tI47OSS3vGedFLKroArECtNjtlePtYmQBjs5Wp9h4xxGUMh&#xA;MwOo2P6mCZunzxNPLvlrWfMWorp+k25nnO7noiL/ADOx2UYQLYZMggLL3ryd+R/lrRo0udZC6tqA&#xA;FWEg/wBGQ9+MZ+383+4ZfHGHV5dZKW0dgmusfmt5F0JRawz/AFtovhFvYIrooHQBqpFT2DZttP2T&#xA;nyC64R57ftRDR5J78vexO5/5yDXkRbaIStfheS4oae6rGf8AiWbKHs8f4p/Z+1yR2b3y+xTtv+cj&#xA;7Tnxu9CkjUGjNFcLIfnxaOP9eczmPBMx7iQwl2eehZboP5yeQ9YZYTeGwnfYQ3qiIGv/ABYC0f3t&#xA;gEwXHnpMkelqfmv8n/J/mKI3FrEum3zjkl3aACNq7gvEKIwPiKE+OCUAVxaqcOe4eB+cPI2v+VL4&#xA;W+pw1hkJ+r3kdTDKB/K1BQjup3ymUSHa4s0ZjZX8jeYf0dqH1SdqWd2QCT0STorfI9D/AGZrO0dN&#xA;4keIfVH7nsfZTtn8rm8KZ/dZD8pdD+g/seo5zj627FUj853/ANS8vXTA0eYegnzk2P8AwtczNBj4&#xA;8o8t3Qe02r8DQzPWXpH+dz+y3kedQ+Lq1rd3dpOtxaTSW86GqTRMUdT7MpBGJCg09G8r/wDORP5o&#xA;6CURtSGrWq0H1fUl9c0/4ygrN/w+US08C3w1Mx1t7T5O/wCcrvJ2plLfzFaS6HctQeutbm2J6VLI&#xA;okX/AIAgeOY09LIct3Khq4nns9m0rV9K1ayS+0u8hvrOT7FxbusiH25KSK+2YxBHNygQeSLwJdir&#xA;sVdirsVeUfmb/wA5EeUvJ7Tadp9Na15Kq1tC1IIW/wCLphUVH8i1PY8cyMWnMtzsHHy6mMdhuXzD&#xA;56/Nnzx51lYazqDCxrVNNt6xWq9x8APxkdi5Y++Z0MUY8nAyZpS5sYsdM1C/k9Ozt3nYdeI2HzPQ&#xA;fTjkzRgLkabtJoc2olw4oGZ8v0nkPiyrTfy1vpKPqFwtuveKMc3+ROyj8c1uXtaI+kW9fovYfNLf&#xA;NMQ8huf1feyWw8j+XbShNv8AWZB+3Oef/C7J+Ga/J2hll1r3PVaT2V0OH+DjPfLf7Pp+xO4YIYUC&#xA;QxrGg6KgCj7hmHKRO5d/jxQgKiBEeWypkWx2KsZ89a7+jtLNtC1Lq8BRfFY+jt+NBmx7O03iTs/T&#xA;F5X2s7W/Lafw4n95k290ep/QP2MD8r+WtS8ya1b6Tp6VmmNXkP2I4x9qRz/Ko/p1zpALfHsmQQjZ&#xA;fS+n6d5U/LnyszEiGCMA3FwQDNczU227s2/Feg+VTmfptNLJIQgLJdOTPNN4x5y/MjzB5quDaxl7&#xA;XTWbjDp8JJL1O3qEbyMfDp4DOy0XZuPTizvLvP6O52+DSxxi+Z7028tfkh5i1KNLjVJV0qBxVY2X&#xA;1JyOorGCoX/ZNUeGY+p7cxwNQHGfsa8uvjHaO7OrL8jfJcFDO11dmm4klCivsI1Q/jmpn25nPKh8&#xA;P1uHLtDIeVBWuvyQ/LqaPilhLbuRvLHcTFq+P7xnX8M00xxSMjzLWNZk72FeZf8AnHe4ijaby7fm&#xA;4K7i0vOKuf8AVlUBSfmo+eVHF3ORj1/84MR8ueePOv5f6mdOu45Pqsbf6RpN1ULQn7UTGvCvZl+E&#xA;++QEjFyMmGGUWPmz78wvzb8oan5L+rWcK6hd6mhAtZ1p9VI25yU6Op+xxPv06zlMU4uDSzjOztTw&#xA;jKXZvVPJGv8A6T0z0JmreWgCSE9WT9l/4HOb7Q03hzsfTJ9f9le1/wA1p+CZ/e49j5jof0H9rJM1&#xA;71Dz38zNR53Nrp6naJTNKP8AKbZfuAP35veycVAz79nzX251vFkhgH8I4j7zsPs+9imlabNqWoQW&#xA;UJo8zU5HcKAKsfoAzZZsoxwMj0eO7P0UtVnjijzkfl3n5MxuvyxIiBtL6so6rKlFP0qSR9xzVQ7X&#xA;39UdvJ7fUewnp/d5fV/SG32cvkWL6n5Z1vTatc2zekP93J8aU9yvT6c2OHV48nI7vJ67sLV6XfJA&#xA;8P8AOG4+Y5fGkrzJdQnXlbzn5o8q3313QNRmsJzT1BGaxyAdBJG1UcezA5GUBLmyhMx5Ppj8sP8A&#xA;nJ7RdceHS/NqR6Rqb/DHfoSLOVu3LkSYWP8AlEr7jpmDl0xG43c/FqgdpbPc1ZWUMpBUioI3BBzF&#xA;ctvFWpJEjRpJGCRoCzuxoABuSScVfKn50/8AORl5rDz+X/J072ukCsd3qiVSa56grEeqRHx2ZvYb&#xA;HPw6et5c3X59Te0eTwyysbu9uFt7WJppn6Iv6z4D3zIyZIwFyNBr0ulyZ5iGOJlIs90P8uraELNq&#xA;r+vL1+roSIx/rN1b/Prml1HahO0Nh3vonZXsXjhU9SeOX80fT8TzP2D3swgt4LeIRQRrFEv2UQBV&#xA;H0DNVKRkbJsvbYsMMceGAEYjoNlTItrsVdirsVWTSxwxPNKwSONS7segVRUnDGJJoMMmSMImUjUY&#xA;iz7njev6vJq2qTXjVCMeMKH9mNfsj+J986zTYBigIvh3a/aMtZqJZTy5RHdEcvx3voP8mvKEPl7y&#xA;qNUvFEd/qaC4nkeg9O3AJjSp+yOPxt89+mbDHD5l5TV5eOdDkHl35gecbzzd5gCWwdrCF/R0y2UE&#xA;luR48+PUvIe3yGd12fo46fHZ+o7yP47naabAMUd+fV6t+X35eaZ5T079L6uYzqojMk88hX07VKEs&#xA;qMdgafab6Bt15/tDtGeolwQ+joO91up1Jynhj9P3sU85fnxdqZrfyxbqsS/CNQuFJY/5UcR2Htzr&#xA;7gZDVdk5MWDxDz6juDfi7P2uXyeWal53836lIXvdYu5a/sCVkQfJEKoPoGaEyLlxwwHIBSsvNvmm&#xA;xk9S01e8hbvxnkofmK0P04OIqcUTzAekeTvz+1S2mjtfM8YvLU0U30KhJk92RaI4+QB+eWRyd7iZ&#xA;dCDvFNvzr81+RtQ8v20EPpanqlwolsLmBt7eMndnYfzUp6Z+mlMOSQpr0eKYl3B4XlLs3YqmOgav&#xA;LpOqQ3iVKKeMyD9qM/aH8R75RqcAywMXZ9kdoy0eojlHL+Id8ev7PN7El1bvbC6WRfq7J6glrReF&#xA;K8q+FM5QwIPDW77dHPCWPxARwVd9K73jWt6i2o6rc3h6SuSgPZBsg/4EDOs0+Lw4CPc+G9qa06nU&#xA;zy/zjt7uQ+xln5aaXV7nU3Gy/uIfmaM5/UM1na2bYQHvey9h9BZnqD09MfvP6PtZ9mkfRnYqkWr+&#xA;TND1Lk5i+rTnf1oaKSf8pfsn7q5m4Nfkx9bHm892j7M6TVWeHgn/ADo7fMcj9/mwXXPJWr6YGlUf&#xA;WrUf7tjBqB/lJ1H4jNzp9fjybcpPnvavsvqdJch+8x94/SOn2jzY9mc829q/JD8/b7yvcQaB5kme&#xA;58tOQkM7VeSyJ2BB6tD4r26r4HGz4OLcc3Kwajh2PJ9cwzQzwpNC6ywyqHjkQhlZWFQykbEEdDmu&#xA;dk+d/wDnKX80ZrVF8i6VMUknRZtblQ7iN947f/Zj439uI6E5maXF/EXC1WX+EPnDSdKutUvo7O2F&#xA;XfdmPRVHVm9hmTmzRxx4ijs7s/Jq8wxY+Z+wdSXrWh6DYaPaiG2Wsjf3s7Ac3Pv7eAzmNRqZZZWf&#xA;k+y9ldkYdFj4MY36y6n8dAmWY7tHYq7FXYq7FXYqwz8xdb9C0TS4WpLcfHPTtGDsP9kR+GbbsvT3&#xA;LjPIcve8N7adqeHjGnifVPeX9Xu+J+webFfJOhjXPNml6Ww5RXE6+sP+Kk/eS/8ACKc6CIsvluaf&#xA;DAl9AfnNrx0rye1nA3CfU3FsoBoRCBylI9qAIf8AWzoOxtP4mazyjv8AqdZocfFks9GE/kZ5XS91&#xA;a4125TlDp1I7UEbGdxu3/PNPxYHNp27qjGAxj+Ln7nM7QzVHhHVd+dnnSa61E+W7OQrZ2nFr4qf7&#xA;yYjkFNOqxj/hvkMexNEIx8WXM8vd+1GgwUOM8y8iubg1MadOjHMLtntc2cWPlykf0D9Lnykhc5Zg&#xA;7FXYq7FXYq7FXYqiF1G/W1NotzKLU9YA7cPH7NaZDwo8XFQvvcka3MMfhicvD/m2a+XJQVWdgqir&#xA;MQFA6knJk048YkmhzL2jQtMXTNJtrMU5Rp+8I7u27H7znJajL4kzJ917J0I0umhi6xG/vO5+1H5Q&#xA;7F2KuxV2KsU8y+RrS/V7nT1W3vepQbRyH3H7J982ek7RlDaW8fueO7c9lMeoByYQIZe7+GX6j5/P&#xA;veazwTQTPDMhjljJV0YUII7HOgjISFjk+W5cUscjGQqQ5h9Nf84sfmdLdwyeRtUmLy2yGfRZHNSY&#xA;l3kt6n+SvJP8mvZRmFqsX8QcvSZb9JfPnnXzBN5i826vrcrFjf3UsyV7RliI1+SoAozMhGgA4U5c&#xA;UiWafl7pKWuj/XWX9/eEtyPURqSFH09c5/tPMZZOHpF9W9juzxi0vikevL/uRyH6WVZrXr3Yq7FX&#xA;Yq7FXYqp3E8VvBJPK3GKJS7t4KoqclGJkQBzLXmyxxwM5bRiLPweL6vqUupajPey/alaqr/Ko2Vf&#xA;oGdbgxDHARHR8J7R1stVnlll/EfkOg+AZ9+QFqs/nt5DStrZTSr8yyRfqkzJx83Ta41D4p//AM5A&#xA;XrvrOlWR+xDbPMPnNJxP/JkZ2Hs/D0Sl5j8favZsfST5s3/KG3t7D8vLW5Pw+uZ7m4PusjJXf/Ij&#xA;XNX2tIz1JHdQcPWkyykPnjU7+e7ubq+nblcXEjzSN4vIxYn7znT6uf5fTkx/hjt9wd2Bwih0SbPO&#xA;WDsCuxV2KuxV2KuxV2KuxVkvkLSPr2tLcOtYLICVvDn/ALrH37/Rmv7Sz8GOhzl+C9V7I9nePqxM&#xA;j0YvV8f4f1/B6nnNvrrsVdirsVdirsVYX+Ymhxy2g1aJaTQUWen7SE0BPup/DNt2XqCJcB5Hk8L7&#xA;Z9lRni/MxHqhtLzHT5H7PcxjyL5hl8u+cdH1uNin1G7iklINKxFuMq/JoyynN5OPFEh81xy4ZApN&#xA;cQS29xLbyrxlhdo5FPZlNCPvGSYF635QuI5/LliyfsR+mw8GQlT+rOW10SM0n2v2czRyaHER0jXx&#xA;Gyc5iO8dirsVdirsVdirDvzG1f0LCPTY2pLdHnLTqI1PT/ZN+rNr2Xg4pGZ6fe8R7a9peHhGCJ9W&#xA;Tc/1R+s/cXnGb98ven/849Sonne5VusmnyqvzE0LfqXLMXNwtcPR8U0/P2Fx5m0+Yj4Hsgit4lJX&#xA;JH/DjOy9nz+7kP6X6GXZx9B970D8tkGoflhZW5P97BcW7UNCP3kie/bNP2j6NVI+YP6XC1XpzEvm&#xA;26RhHIhFGXqD1BBzpu1YeJpZgd1/Ld3h5JdnnbW7FXYq7FXYq7FXYq7FXYq9c8naP+jNEiVxS4uP&#xA;301eoLDZf9iv45y+uz+JkPcNn2f2a7N/K6SIP1z9UvjyHwH22nmYb0DsVdirsVdirsVSjzZJHH5c&#xA;1BpPsmIqP9ZiFX8TmVogTmjXe6b2hnGOhyk/zfv2H2vIoIZZ544Il5SysEjUd2Y0A+/OqfEXpP8A&#xA;zkL5Km8s/mPfTJGV07WmbULNwPh5Sms6DtVJSduwK5Rp58Ufc36iHDL3sa8k+Z10u5NpdNSxuGB5&#xA;HpG/Tl8j3zF7Q0niDij9Q+16b2W7dGkyeFkP7qZ/0p7/AHHr83pysrqHQhlYVVhuCD0IOc6RT6xG&#xA;QIsbgrsDJ2KuxV2KtEgAkmgG5JxQTW5eN+Y9VOqaxcXdaxFuEA8I12X7+udZpcPh4xHq+HdtdoHV&#xA;6qeT+G6j/VHL9fxSzMh1TLfyp1ddK8/aTPI3GGaQ20m9BSdTGtfYOynJwNFo1MOLGXrf59aM9zoN&#xA;lqsaknT5jHLQdI7gAcifZ0UfTnTdg5uHIYfzh9zh9nZKkY96E/IPX0ezv9BkaksT/W7YHqUeiSAf&#xA;6rBT/sss7f09SGQddj+PxyZ9o49xL4MJ/NfyvJofmu4kRKWOpM1zatT4asayp4fC56eBGbTsrUjN&#xA;hAPOOx/Q5ejzccPMPPZ4TG232D0Ocn2p2bLTzsf3Z5H9DcRSlmqQ7FWwrNUgVpuctx4JzBMQTw81&#xA;aypXYq7FXYqn3kzRf0nrMfqLW2tqSzV6Gh+FfpP4VzC1+fw8e3M7PRezPZn5rVDiH7uHql+gfE/Z&#xA;b1rOYfZXYq7FXYq7FXYq7FXn35h+YEmddIt25LE3O6YdOY6J9HU5vOzNMR+8PwfNvbLtgTI00DtE&#xA;3P39I/Dr5+5Mv+cf/JU3mf8AMfT3aMtp2kOuoXz0+EeieUKf7OUKKeFfDNlqJ8Mfe8Rp4cUvc+qf&#xA;zZ/Lax8/eVZdMkKw6lbkzaVeMP7ucCnFiKn05Psv9/UDMDFk4DbsM2LjFPhvWtF1PRNVudK1S3a1&#xA;v7RzHPC4oQR3HiCNwRsRvm0jIEWHUyiQaKaeXPOV9pPGCUG5sa/3RPxJ/qH+HTMLVaCOXcbSel7E&#xA;9ps2jqEvXh7uo/qn9HL3PR9K1zTNVi9SzmDkCrxHZ1/1lO/8M0GbTzxmpB9Q7P7V0+rjxYpX3jqP&#xA;ePwEflDsXYq7FWP+eNV+oaFKqNSa6/cR+NG+2f8Agczuz8PHlHcN3m/artD8vo5AH15PSPjz+z73&#xA;lABJAAqTsAM6Z8dAvYMuk/LjUU0w3InVrsJza0C+1Soeu7fRmrHasDOq9Pe9pP2Kzx0/icQOSr4K&#xA;+zivn8OfViKsyMGUlWU1BGxBGbR4p9VeVtW0/wA+eQ1N1RzdQm11FBSqTqoDEbUBrR18NsztPmMJ&#xA;CY5h0mSJxZNunJ4Sw1zyN5v/AJL7Tpagn7EsZ/40kQ/5nO6/d6vD5S+w/sd16c2PyL3aSPy1+Y/l&#xA;IUb93JQhhT1ra4UdCPEV/wBkPnnJg5dFm/FEOmHHgn+N3gvnDyZq3le/FnqKq8U3I2twhqkqLSpA&#xA;6gjkKg/251On1mHVRrbfnE/jd3OHPHILDG2s4yaglcwM3s7gkbiTH7R+Pi28LS2UY6kn8Mhi9nMQ&#xA;PqlKX2I4VUtFCvZR2Hc5s8mXT6PHW0R3dT+tlsEA5DOSq0B3oM4LUSGXIZQjQO9BrK3MZDsVd12G&#xA;KvXPKGiforSESRaXU/724PcEjZf9iPxrnL67UeJk25Dk+0eznZf5PTAEfvJ+qX6B8B9tp5mG792K&#xA;uxV2KuxVpmVVLMQFAqSdgAMKCQBZYT5o8+xxq9npD85TVZLsfZX2j8T/AJWbfR9mk+rJy7v1vBdv&#xA;e10Yg4tMbl1n0H9Xz8+XdbEvLvl3WvM2tW+kaRbtd6hdtREHbuzux+yq9WY5upSERZfOQDM95L7f&#xA;/Kj8tNO8geWU0yBln1C4Il1S9Ap6s1KUWu/BOiD6epOazLkMzbtMWIQFMzyptef/AJr/AJOeX/zA&#xA;sA0tLLXbdaWeqIoLUFT6cw25x1PjUdu4N2LMYe5pzYRMeb4987/l75q8l6mbDXbNoQxP1e7SrW86&#xA;j9qKSlD7j7Q7gZsYZBIbOsnjMTRY9DNNDIssLtHIpqroSrA+xGSlEEUVx5ZQkJRJjIdRsyzSPzF1&#xA;K3Cx38Yu4ht6g+CQf8at/nvmsz9lwlvH0/c9j2d7aZ8VRzDxI9/KX6j+N2Y6Z5s0LUaLDciOU/7p&#xA;m+B6+ArsfoJzVZtFlx8xt5PcaH2h0ep2jPhl/Nlsf1H4EpxmI7t5h+YWp/WtaFqhrFZLw9ubfE/8&#xA;B9GdH2Zh4cfF1k+Te2Wu8bVeGPpxCvidz+gfBB+S9N+v6/bqwrFb/v5Pkn2f+Gpluvy8GI952cH2&#xA;Y0P5jWwB+mHqPw5fbT1vOXfZ3l3nvQf0fqX1uFaWl4Swp0WTqy/T1GdH2dqeOHCfqj9z5J7W9kfl&#xA;s/iwH7vJv7pdR+kfHuR35W+f5PKWtn6xyfSL3il9GNytD8MqjxSu47j6M2kJUXitTg8SPmHuHnvy&#xA;PpnnXSIbuymjF+kfPT75SDHIjfEEdlrVG6gjp18Qd12d2gdPLvgeY/SHX6fUHFKjy6vENP1PzX5G&#xA;111QPZ3kZAuLWUVjlUHbkAaOp7Mp+Rzq8mLDq8feO/qHbyhDNHvCA89eaNU81a2dUuVEaKixW9sh&#xA;JWNFG4FaV5NVs5bWdiZ8cuKHqHlz+X6kYsHhigx31rhNiSPn/bmKO0tZh2MpD+sP1hssu+sTtsGP&#xA;0DCe1tXk2Ej8AP0C1stpbTOatt7t1yzB2Pqc8rn6fOXP5c0iJRUcUcS1+9jnVaTQ4dJAn5yP42DI&#xA;CkFMYzISgoucR2hPFLMTiFQ/HLuDArMwkMn8h6F+kNU+tTLW1syHNejSfsL9HU/25ru0dRwQ4R9U&#xA;vues9kuyfzOo8SQ/d4t/fLoP0/2vUc5x9bdirsVdiqySWOJDJI4RF3Z2IAHzJwgEmgwnOMBcjQHe&#xA;xvVvP+i2YZLYm9mHQR7R193P8K5sMPZuSfP0h5ftD2v0uCxj/ey8vp/036rYNrXmrV9Wqk8np23a&#xA;3i+FPp7t9ObnT6PHi5DfvfPu1PaDU6zaZ4YfzY7D49T8WQfl1+T/AJx89XKnTrY2+lBuM+rXAKwK&#xA;AfiCd5GH8q/TTLcmaMObqceGU+XJ9e/lv+VflfyFpv1fS4vWv5lAvdUlA9eY9af5CV6Iu3jU75rs&#xA;mUzO7ssWIQGzMcrbXYq7FUFrOiaRrWnyadq1nFfWM395bzoHQ06Gh6EdiNxhEiDYRKIIovAPPv8A&#xA;zibbytLe+Sr70GNW/RV6SyeNIpwCw9g4P+tmZj1f85w8mk/mvA/NPkTzf5VuDDr+lT2O/FZnXlC5&#xA;/wAiZeUbfQ2ZcckZci4c8co8wkOSYJhaa/rVpEYbe9ljipQIGJA/1a1p9GUT02ORsxFuy0/bGrwx&#xA;4YZJCPdf3d3wQDMzsXclmYksxNSSepJy8CnXSkSbO5L0T8tNPEdhcX7D4p39ND/kR9afNj+GaHtb&#xA;LchHufTfYfR8OGeY85mh7o/tP2MzzUvcoHWtKg1XTZbOXbmKxv8AyuPstl2nzHHMSDr+1Oz4avBL&#xA;FLryPceh/HR43d2s9pcy2068JoWKOvuM6yExIAjkXw7UaeeHJLHMVKJos3/Lj819T8qOtldBrzQ2&#xA;arW1RziJ6tCT95U7H2O+WxnTr9RphPcbSe5FPI35haOsgMV/Co+F1PC4gZux6Oh26HY+4zP02rni&#xA;NwNOtEsmGXc88178hNSidpNDvo7mLcrBdVjkA7AOoKMfchc6LB2/E7ZI17nPx9oj+IMRu/yv8+2x&#xA;pJo8r12BiaOUf8k2bNjHtXTyH1fe5Q1eI9WK3BFtNJBN+7mhZo5IyN1ZTRgR7HIntbSxH1j7W8SB&#xA;Q73iD7IJP3DNdqPaPFH+7BkfkP1oMkNJNJIfiO3gOmc3rO0cuoPrO3cOTEm1mYKHYq9m8vabb6dp&#xA;Fvbw0YFQ7yD9t3FS39PbOT1WU5MhJfc+xtDDTaaEId1k95PM/jomJIAqdgOpzHdmSl935h0O0r69&#xA;9CpHVAwZv+BWpy+GlyS5RLrdR2zpMP15ID42fkLKS3n5j6JDUW6S3LdiF4L97fF/wuZmPsrIedB0&#xA;Op9tdJD6BLIfdQ+3f7GP335kazNVbWKO1U9Gp6jj6W+H/hczsfZWMfUTJ5vV+22qntjjHGP9Mft2&#xA;+xjl7qeoXz87y4knI6B2JA+Q6D6Mz8eKEPpFPMarXZ9QbyzlP3n8UyryX+T/AOYHnApJpOluli9P&#xA;9yN1+4tqHuHYVf8A55hsZ5ox5lphhlLkH0L5C/5xa8paKY7zzLKdev1owtyDHZof9SvKT/ZGh/lz&#xA;Dyaonls5uPSxHPd7VBBBbwpBBGsUMahY4kAVVUbAKo2AGYrlL8VdirsVdirsVdiqnc21vcwPb3MS&#xA;TwSCkkUih0YeBVqg4gqQ8180/wDOOf5X6+Xlj09tHumqfX01hCtf+MJDw0+SDL46iY82iemgfJ8/&#xA;fnF+RY/LzT7bU49aS/truf6vDbPEYpweDOW2Z1ZV47nbqNsy8Ofj2pws2DgF28ozIcd7Todj9Q0i&#xA;0tKUaKNeY/yz8T/8MTnI6jJx5DLvL7v2VpPy+lx4+sYi/fzP2o/KXYOxVhf5g+XfXh/S1sv72EUu&#xA;lH7UY6P817+3yzb9maqj4Z5Hk8J7Y9jeJD8zjHqj9XnHv+HXy9zzvN6+ZorTtT1HTbpbrT7mW0uU&#xA;+zLC5RvlUdvbCCxlEEUXouif85AebrJVj1KCDU416uw9GU/7KP4P+EyYyFxJ6GB5bMrtf+cjdEZa&#xA;3Wj3MT+EUkcg+9vT/Vk/FDQdBLoXiOs3sd9rF9fRqVjuriWdFalQJHLAGnffKS7KAoAIPAydirsV&#xA;diqY2/mLXLa3FvBeypCooqBug8AeoyiWlxyNmIt2eHtrV4ocEMkhEdL+5C3N/fXX+9NxLP8A8ZHZ&#xA;/wBZOWRxxjyADiZtXmy/3k5S95J+9QybjuxV7J+Uf/OPY896JHr1xriWlh60kMtrBEZJw0Z3UsxV&#xA;EqCGGzbHMbLqOA1Tk4dPxi7fQflH8ivy08rsk1ppS3t6lCt7qB+syAjoVVgIkPuqDMSeeUurmwwQ&#xA;j0Z+AAKDplLc7FXYq7FXYq7FXYq7FXYq7FXYq+X/APnMHWC+s+XtGB2t7aa8dfH15BGpPy9BqZna&#xA;QbEuBrJbgPC/Lln9c12ytyKq0qs48VT42/Bct1WTgxyPk39i6bx9Zjh0MhfuG5+wPZs5J9zdirsV&#xA;aZVZSrAMrChB3BBwgoIBFHk8m83+XW0fUCYgfqVxVrdv5fFD8v1Z02h1Xiw3+oc3xv2j7GOiz+n+&#xA;6nvHy74/D7khzNedXIjyOsaKWdyFVQKkk7AAYCa3LKEDIgAWSnY8j+aSARY7HfeSIH7i+Yn8oYf5&#xA;32H9Tvx7K9okX4f+yh/xTY8i+aa/7xU9/Vi/5rwfyjh/nfYf1JHsn2j/AKn/ALKH/FKq+QPMxNDA&#xA;gHiZE/gcj/KWHv8AsbR7Ia8/wj/TBVT8ufMLfaMCb/tOf+NVORPamLzboexetPPgH+d+oFExfllq&#xA;p/vbuBfHjzb9YXKz2tDoC5cPYXUH6skB7rP6AjIfyvTrNqBPiEip+JY/qyqXa/dH7XNx+wY/iy/K&#xA;P/HkfB+W2hJvJLPKe4LKo/Ba/jlEu1ch5AB2GL2I0cfqlOXxA+4fpTG38meWoN1slc+MjO/4MSMo&#xA;lr8x/idph9mdBj5YwfeSfvKZQ6bp0KFIbWGNDsVSNVB+4ZjyyzPMl2mPQ4ICowhEeUQHlPm7T4rD&#xA;zBdQQoEhJWSNRsAHUEge1a502iymeIE83x72j0cdPrZwiKjsR8Rf329+/wCcPtdrb+YdAdvsPDf2&#xA;6f64MUx/4WPIauPIuDo5cw+j8wnOdirsVdirsVdirsVdirsVdirsVdir4u/5ya1L65+beoQhuS2E&#xA;FtbKRuP7oTEfQ0xzZ6YVB1eqNzYt+W9t6muSTHpBCxH+sxCj8K5h9qzrGB3l6n2JwcWrM/5kD8zQ&#xA;+63pmc8+rOxV2KuxVA6zpNtqunyWc4oH3Rx1Rx0YZdgzHHISDgdp9nY9ZhOKfXke49C8e1HT7nT7&#xA;yW0uV4yxGh8COzD2OdViyicRIci+I63R5NNlliyCpR/F+4rtKvvqOpW15x5iCRXZfEA7096Y5sfH&#xA;Ax7wy7P1X5fPDLV8EgXs1neW95ax3Vs4eGUckYf59RnJZIGEjE8w+6abUwz4xkxm4y5K+Qb3Yq7F&#xA;XYq7FXYq7FXYq83/ADMt+OrW04G0sHE/NGP8GGb/ALJlcCO4vl3tzhrUwn/OhXyJ/Wyr/nF/WDYf&#xA;mtbW3Kiapa3Fo1enwp9YH4wZm6kXB5LSmpvszNa7N2KuxV2KuxV2KuxV2KuxV2KuxV2Kvgr84b03&#xA;n5peaJS3LjqM8Nd/90N6NN/Dhm2wioB1GY3Mo38r4aRahN4tGg+gMT+vNR2vLeI976D7B4/Tln5x&#xA;H3/rZ1mmfQXYq7FXYq7FWOecvLK6tZ+vAv8Ap9uD6f8Alr1KH+GZ+h1fhSo/SXmPaXsMazFxwH76&#xA;HLzH839Xn73lbKysVYFWU0IOxBGdKC+QEEGjzZD5Q80vo9z6E5LafMf3g6lG6cx/EZga7R+KLH1B&#xA;6b2c7fOiycE/7mXP+if5w/S9UjkSRFkjYOjgMrKagg7ggjObIINF9ehMSAINgrsDJ2KuxV2KuxV2&#xA;KuxVg35oRVg0+X+VpF/4IKf+Nc3PZB3kPc+f+3mP0YpdxkPnX6ku/KK/Nj+Z/lecEry1G3hJHhO4&#xA;hPcbUffNvmFwL55hNTD74zUu4dirsVdirsVdirsVdirsVdirsVdir89vPrvJ558xSOeTvql6zMe5&#xA;Nw5JzcY/pHudNk+o+9lX5Zf8cm6P/F//ABouaLtb6x7n032F/wAWn/X/AN6GY5qnt3Yq7FXYq7FX&#xA;YqwTz95XUq+sWi0I3vIx37eoP+Nvvzddm6z/ACcvh+p899ruwRR1WIf1x/vv1/PvYFm6fOmW+TPN&#xA;x0910++f/QXP7uQ/7qY/8an8M1mv0XGOKP1fe9l7Me0f5YjDmP7k8j/NP/E/dzelAhgGU1B3BHQj&#xA;OffVAQRYbwJdirsVdirsVdirDvzN/wCOTa/8Z/8AjRs2vZP1n3PEe3X+LQ/r/wC9LD/KExg82aJM&#xA;ByMV/avx6V4zKaZvZ8i+Yw+oP0PzTu6dirsVdirsVdirsVdirsVdirsVdir8+fzChaDz95lhbdot&#xA;VvUJHQ8bhxm3x/SPc6bJ9R97JPyxlB0+9i7rKrH5MtP+Nc0va49cT5PpXsJMHBkj3SB+Y/YzTNQ9&#xA;07FXYq7FXYq7FWE+dvN1stvNpVkRLLIOFxKN1Qd1Hi3j4ZuOz9EbE5bDo8F7Ue0eMQlpsXqlLaR6&#xA;DvHmfu9/Lnubx81dirLvKHnN7ApYagxayJpFKdzFXt7r+rNXrtBx+qP1fe9p7Oe0x09YcxvF0P8A&#xA;N/479z0iORJEWSNg6OAyspqCDuCCM0BBBovqMJiQBBsFdgZOxV2KuxV2KsM/M2QDTrOPu0xYfJVI&#xA;/wCNs23ZI9cj5PC+3U/3GOPfP7h+1i/kO1+t+ePL1rx5evqdnHxOwPO4QfxzeZD6T7nzXGPUPe/Q&#xA;nNO7l2KuxV2KuxV2KuxV2KuxV2KuxV2Kvhz8/wDR20v82teTiRHdSJeRMf2hcRq7Ef8APQsPozaa&#xA;c3AOp1EamUq/Le/WDV5rRjQXcfw+7x1IH/Alswe1cd4xL+afvet9idYMepliP+Uj9sd/ut6VnPvq&#xA;jsVdirsVU554YImmmdY4kFXdjQAe5OSjEyNDm15csccTKZEYjmS8980efJbvnZ6WWitjUSXHR3Hg&#xA;vdV/H5ZvdH2cI+qe57nzTt72tlmvFp7jDrLrL3dw+33MPiiklkSKJGklkYLHGoJZmJoAANySc2rw&#xA;76q/In/nH5ND+r+aPNkKyawQJLDTXFVta7iSUHYzeA/Y/wBb7OBn1F7Dk7DBp63lzY7+eH/OOs1v&#xA;JdeZ/JkBltnLTaho0Y+KMmrNJbKOqeMY3H7O2wng1HSTDPpusXzqQQaHrmY4TIvLHnC60hhBNWfT&#xA;yd4/2kr3Qn9WYGr0Mcu42k9N2F7SZNEeCfrw93Uf1f1cvc9N0/UbLULZbm0lEsTdx1B8GHUH55z2&#xA;XFKBqQovq+j1uLU4xkxS4on8b9xROVuU7FXYq7FXnH5lXyy6nb2amv1aMs/s0pBp/wACozf9k46g&#xA;Zd/6Hy/241YnqIYh/BGz75fsA+abf849aG+rfmxoo41hsGkvpz/KIEJQ/wDI0oMz9RKoF4/TxuYf&#xA;b+at2rsVdirsVdirsVdirsVdirsVdirsVfOf/OXHkySa20vzfbR8hbD6hqLAbhHYvA59g5dT7sMz&#xA;NJPnFwtZDlJ81Wl1Na3MVzA3GWFg6H3BrmZOAkCDyLjafPPDkjkgalE2HsOha5aaxYrcQMBIABND&#xA;X4kbwPt4HOV1GnlilRfbeye1cWtwicDv/FHrE/jkeqZZju0dirH9a87aPpoaNH+t3Q29GI1AP+U/&#xA;QficztP2fkyb/SHm+1PajS6W4g+Jk7o/pPIfafJ53rfmTU9YkrcycYVNY7dNkX6O59zm90+lhiG3&#xA;PvfM+1O29RrZXkPp6RHIfrPmVPQtB1jXtUh0vR7SS9v7g0jgiFT7knoqjux2GZEpACy6mMSTQfXP&#xA;5N/kFpXktItY1nhqHmcrVXpyhtKjdYa9X8ZPoFN667NnMthydlh04jueb13MdyXYq8U/OL/nHXTf&#xA;M5m1zywI9P19qvPbfYt7pupJptHIf5uh/a/mzKw6gx2PJxc2mEtxzfKOsaNqui6jNpuq2sllf27c&#xA;ZreZSrKe3zB6gjY5niQIsOulEg0WtM1bUNMuBPZTGN/2h1Vh4Mp2OV5sMcgqQczQ9o5tLPjxS4T9&#xA;h94Z7o35iadchY9RX6pP0Mgq0R/42X/PfNJn7LnHeHqH2vovZntngygRzjw59/OP6x+N2VW9zbXM&#xA;Ylt5UmjPR0YMPvGa2UDE0RT2GHPDLHihISj3g2q5FtSnXvMen6Pbs0zh7gj91bKfjY9q+A98ydNp&#xA;Z5Tty73T9rdtYNFAmRufSPU/qHm8kvbye8u5bqduUszF3Puew9hnUY4CEREcg+L6rUzz5JZJm5SN&#xA;l9P/APOJnkmSy0XUPN10nGTVD9U0+o3+rwtWVx7PKAP9hmHq52acnSQocT6AzEcx2KuxV2KuxV2K&#xA;uxV2KuxV2KuxV2KoLW9G07W9Ju9J1KEXFhexNDcRHurCmx7EdQR0O+GJINhEogii+IPzV/KfXfIO&#xA;svDOj3Gizuf0dqYHwOp3CSEbLKB1X6Rtm0xZRMebqcuEwPkwu0vbuzmE9rM0Mo6OhINPA+2SnjjM&#xA;VIWGWn1WTBPjxyMZd4TxPP3mZU4m4Vj/ADmNK/gAMxD2bh7vtd/H2u14FcYP+bH9SX3/AJj1u/Ur&#xA;dXkjoesYIRD81XiMvx6XHD6Yh1ur7a1eoFZMkiO7kPkKCWgEmg65e6t6t+Xf/OOvnfzW8V1qETaH&#xA;orUY3V0pE0i/8UwGjGvZm4r4E5Rk1EY+ZcjHppS57B9U+Q/y38qeR9N+p6Ha8JJAPrV7LR7iYjvI&#xA;9Bt4KKKPDMDJkMju7DHiEBsyfK2x2KuxV2KsU8//AJZeU/PWni21u2/0iMEWuoQ0S5hr/I9DVfFW&#xA;qvtlmPKYnZryYozG75T/ADH/AOcfvOvk5pbu3iOs6ItSL+1Ql41/4vhHJk/1hVffM/HqIy8i67Lp&#xA;5R8w8wy9oVIZ54X5wyNG/wDMhKn7xglEHmGzHlnA3EmJ8jSKOu62V4nULkr0oZpKfryr8vj/AJsf&#xA;kHMPa2rIrxclf15frQTMzMWYlmO5J3Jy4BwJSJNnmzz8pPyn1fz/AK4sSK9voVs4Op6iBQKvX0oy&#xA;djKw6eHU+9WXKIDzbcOEzPk+4NM02x0zTrbTrCJYLKziSC3hXoscY4qN/YZqybNu1AoUETgS7FXY&#xA;q7FXYq7FXYq7FXYq7FXYq7FXYqhtT0vTdUsZbDUrWK8spxxmt50WSNh13VgRhBI5IIB2LxfzP/zi&#xA;b5K1GZptCv7nRGf/AHQR9bgX/VV2ST75DmTHVyHPdxZaSJ5bMOf/AJw+18SUTzHatFt8TQSK3v8A&#xA;CGP68t/Njua/yZ7060f/AJw90tHVtY8xzXCV+KK0t0gNPaSRpv8AiGQOrPQMo6MdS9T8ofk3+XXl&#xA;Nkm0vSI3vkoRf3VbicMP2laSoQ/6gXKJ5pS5lyIYYx5BmuVNrsVdirsVdirsVdirsVefedPyI/Lj&#xA;zY73F1p31DUJKlr/AE8iCQk9S60aJyfFkJ98uhnlFpnp4yeRa3/zh/q6SM2heYLeeM14R30TwkeA&#xA;Lxety+fEZkR1Y6hxpaM9CkUX/OJf5lNMUe90qOMf7tM85BFewEHL7wMn+bj5sPyk/JnHlH/nEfR7&#xA;WeO4806s+ohd2sLRTBET4NKSZGX/AFQp98qnqz0DbDRjqXu+j6NpWjadDpulWsdlY244w28KhUUd&#xA;T06knck7nMQkk2XMjEAUEZgS7FXYq7FXYq7FXYq//9k=</xmpGImg:image>\n               </rdf:li>\n            </rdf:Alt>\n         </xmp:Thumbnails>\n         <xmpTPg:NPages>1</xmpTPg:NPages>\n         <xmpTPg:HasVisibleTransparency>False</xmpTPg:HasVisibleTransparency>\n         <xmpTPg:HasVisibleOverprint>False</xmpTPg:HasVisibleOverprint>\n         <xmpTPg:MaxPageSize rdf:parseType=\"Resource\">\n            <stDim:w>190.000000</stDim:w>\n            <stDim:h>190.000000</stDim:h>\n            <stDim:unit>Pixels</stDim:unit>\n         </xmpTPg:MaxPageSize>\n         <xmpTPg:PlateNames>\n            <rdf:Seq>\n               <rdf:li>Cyan</rdf:li>\n               <rdf:li>Magenta</rdf:li>\n               <rdf:li>Yellow</rdf:li>\n               <rdf:li>Black</rdf:li>\n            </rdf:Seq>\n         </xmpTPg:PlateNames>\n         <xmpTPg:SwatchGroups>\n            <rdf:Seq>\n               <rdf:li rdf:parseType=\"Resource\">\n                  <xmpG:groupName>Default Swatch Group</xmpG:groupName>\n                  <xmpG:groupType>0</xmpG:groupType>\n               </rdf:li>\n            </rdf:Seq>\n         </xmpTPg:SwatchGroups>\n         <dc:format>application/pdf</dc:format>\n         <dc:title>\n            <rdf:Alt>\n               <rdf:li xml:lang=\"x-default\">connect-query</rdf:li>\n            </rdf:Alt>\n         </dc:title>\n         <xmpMM:DocumentID>xmp.did:ef71b652-b2a1-4a4e-86d6-63c0de777b3d</xmpMM:DocumentID>\n         <xmpMM:InstanceID>uuid:fe6fd78e-c88a-4c95-8b8a-014f7e1940d4</xmpMM:InstanceID>\n         <xmpMM:OriginalDocumentID>xmp.did:7c4f2302-202b-7840-b399-95443e775df7</xmpMM:OriginalDocumentID>\n         <xmpMM:RenditionClass>proof:pdf</xmpMM:RenditionClass>\n         <xmpMM:DerivedFrom rdf:parseType=\"Resource\">\n            <stRef:instanceID>xmp.iid:41fc62d4-bcde-a748-bf99-2213076a569f</stRef:instanceID>\n            <stRef:documentID>xmp.did:9f50c985-9253-b841-ae5b-ac499933c02f</stRef:documentID>\n            <stRef:originalDocumentID>xmp.did:7c4f2302-202b-7840-b399-95443e775df7</stRef:originalDocumentID>\n         </xmpMM:DerivedFrom>\n         <xmpMM:History>\n            <rdf:Seq>\n               <rdf:li rdf:parseType=\"Resource\">\n                  <stEvt:action>saved</stEvt:action>\n                  <stEvt:instanceID>xmp.iid:7c4f2302-202b-7840-b399-95443e775df7</stEvt:instanceID>\n                  <stEvt:when>2022-11-15T17:39:29-05:00</stEvt:when>\n                  <stEvt:softwareAgent>Adobe Illustrator 26.5 (Windows)</stEvt:softwareAgent>\n                  <stEvt:changed>/</stEvt:changed>\n               </rdf:li>\n               <rdf:li rdf:parseType=\"Resource\">\n                  <stEvt:action>saved</stEvt:action>\n                  <stEvt:instanceID>xmp.iid:ef71b652-b2a1-4a4e-86d6-63c0de777b3d</stEvt:instanceID>\n                  <stEvt:when>2022-11-15T17:42:05-05:00</stEvt:when>\n                  <stEvt:softwareAgent>Adobe Illustrator 26.5 (Windows)</stEvt:softwareAgent>\n                  <stEvt:changed>/</stEvt:changed>\n               </rdf:li>\n            </rdf:Seq>\n         </xmpMM:History>\n         <illustrator:Type>Document</illustrator:Type>\n         <illustrator:CreatorSubTool>AIRobin</illustrator:CreatorSubTool>\n         <pdf:Producer>Adobe PDF library 16.07</pdf:Producer>\n      </rdf:Description>\n   </rdf:RDF>\n</x:xmpmeta>\n                                                                                                    \n                                                                                                    \n                                                                                                    \n                                                                                                    \n                                                                                                    \n                                                                                                    \n                                                                                                    \n                                                                                                    \n                                                                                                    \n                                                                                                    \n                                                                                                    \n                                                                                                    \n                                                                                                    \n                                                                                                    \n                                                                                                    \n                                                                                                    \n                                                                                                    \n                                                                                                    \n                                                                                                    \n                                                                                                    \n                           \n<?xpacket end=\"w\"?>\r\nendstream\rendobj\r3 0 obj\r<</Count 1/Kids[5 0 R]/Type/Pages>>\rendobj\r5 0 obj\r<</ArtBox[0.0 10.0 190.0 180.0]/BleedBox[0.0 0.0 190.0 190.0]/Contents 20 0 R/CropBox[0.0 0.0 190.0 190.0]/LastModified(D:20221115174608-04'00')/MediaBox[0.0 0.0 190.0 190.0]/Parent 3 0 R/PieceInfo<</Illustrator 7 0 R>>/Resources<</ExtGState<</GS0 21 0 R>>/Properties<</MC0 18 0 R>>>>/Thumb 22 0 R/TrimBox[0.0 0.0 190.0 190.0]/Type/Page>>\rendobj\r20 0 obj\r<</Filter/FlateDecode/Length 3365>>stream\r\nHdɎ$\u0011D\u0015y\u0016P9/W\r\u0001\u0004AA\u001fАC7\u0001R\u000fyT75:LDfd/O߯ǯt\u001dۿ\u001e~i-]>~K9\\=hۇ>>\u001eN^{޳Ma1Hw\u001fHj^_Oj㞭vͻ\u0001\u001cdon=\u001e{ar5n[y*{Lf5G\u0012˄W΃\u0015<YeS,|Q}L<Wwsrm1r8X;\u0003[au=wKZ΁{-w#k{N\n׺ںל\"M|N\nY\u001dEcZ\u0017^\u00171rG,\u0017?#p}{s\u0012KYĮ҇|ݐ`\u000bY\u001cKY\b[78V6+9Nr),B\u0006\u0015EO\u0000C#ֻ{LUh]\u001a\fB[J䲿\u0001\u0005])U:;S\t\b\u0002@$j@9ر\u0019Q\u0006n7g!`z\"`]\u001f~\u00190Œ'}Q1\u0002Z`\u00020ϓǵqhW\u0007m˂\u0004\u0002-J]2L\u00067G5\u001a%ǫ\"\t\b\u001d\u0015Rޭ[#r\u001ebMd\\[JqP[!\u00025\u0014.?b?\u0014M,F?\u0005qzo\u0018adN=}:z`jT+-ʐO+e3IV#C\u000b9@$p3y\"o8:1\u0016[&B\u0013Wء2~{('g\u00184}~Q\bxQ&Ղġs[\u0015,UL׊5\u0011IOV\u0012)Xu[D^@\"\u0014P-\u0004ۛ\"g_\u000e\u0014B=5\u0005\u000eƩ\u0002rWD֔eHSGQq\tk,Y[Xv\u0005\u0003\u001d\u0002wF\fѰ#T%e1\bJS\u0011O\u0011hQLv# -Xal\"K5\u0007p`[l\t~5N\u0017%Ô}5/!\u001b.3\u0006\u0000\u0018\u0015\n| ̲\n|PSIq\u0012In\nz\u0013\u0010q0DH'\u0000\nk\u0002?D\fz\u0000)?86z@U-\u001b\u0001ݖ\u0006ۛB+Ɍ+QBM1\u0010#G\u001a(ty]afV\nJz\u0000\"fhW\"Q{rSF1\u0000\u001ax\u0001wB29\u0006f\u0011\f\u0005$3\u0018m``\b^㢰k.9d`σV\u001fI8]DO\u0018T]nQaT5蒣\u0014kvW\u00015\u0005 }d\fN9,\u0014\u0015βZ3\\\u0017Mw\u0007VnW\u0016yRH[:iT{\\4y\u001e/Ou\u0010bU9&\u000b74RpWx\u0016D7 \f6K\u0015\u0007,ы߽=Hz\u0006kz\u001co\u0013(r\u001dnqUZ\u001098\u001bg;:8P6\u0019KEun\u0010M\"6ywNRMD[\u0016a|(ޢH,ՎYM\u0002LsHV\t\nĒj\u0016[IB:\bn\u0018\u0007AnN\u0010jK\u000bm |gg\u0007x>2;[Y\u0006\u0017m\u0003Q\u0011@S\u0005;U\u0016ʸȫ&{7\u0018\t|)\u0016~H\nU\u0013q\u000e\t\u001d*Aƺc2\u001eVD:j4\u0005\u0007\u0011E5c\bz\u0017'T\u00038\u00151Nėכ9@\u0007侸T4\u0005Mx~$WS\u0002\u0016\bRDWx\t\u000e{÷/\u000b\u001c\u0014I\"~9\tϩ\u0001cjwXT#'J=5!\u0018\rm\n\u0007&O\u0018\u001c}1B#D\\\u001e5\u0011/G菽J|P4O\u0018\u001dЊzqceSYmI䥋*$CV\u001c躙Na.':R4$!<G\u000e.!\u001a\u0002\u0002\u0006\u0011250z\fujK\nV\u001e$JS;nZ\"MUBJ0~i)\u000e4XmJ:[wUFʨ3>Fa5G<z5\u000e+!\u001aZ/\u0013֚Pi$7}\nh\"\u0007\u00128bĀ\u0000\u0017t\r1\u0012G.\u001fde\u000e\"<Pehq\u0004\u001f\u0013R'\t\u0013]PW\u0002W\u0017-6l\u0005;%vn Uu\u001fG\u0018,}IƂj\u0015Rzi\u0012t\u0017b5C8)&\u0015(b9C7\u001ep?\u000f`j~Rʏְ\u0012jm\u0016*\u0000LC\u0016\u0018\u001e\u0016\blR2] cD*3N/loX$Yԏx\u001e\u0006\u0013յ\u001erևzL-q\u0005eDMy[\u001e\u0017cApxլؿt+YR!mP\u0013I:Ȳ['Z}Q^c#\"\u0013U!\u0018[<U5M\u0018\u0016t##*3 q\rƗ\u0019Mj\u0006w;\u00062e&\u0019EZ6Ix\rIg(f]M\u0012|\"Eţ&)6'*GM[hh.U!\u0001\u00150dB\u0010k\u0010\\ڶS\u0010\u001e\u0015\u0005\u0004S\n%I&jْhYU\u0003S긯j\u0011eJZ%q߅N*\u0010\u0012Pi-\u0011Kr\u0015f\u0006\u0006\u0011\n\u0014\u0013$\u000fX\u0017t`Sa\\lB\u0014\u0016_gkɣUwT\u000blQ\u0012RJ07_iU\u000f\u0016\\^Y⊜B]lsO\"pc\u0011\tg<NT\u0013BZV\b]<\u0011OǑ> <W߈ˈ,\u0006>mT/\u000b,BQ\u001cS\"\u0019\t8.)]\u00024>#͔k&5\\>\f:S}eM0UmCBj\u0018h\u0016\u0012;P\u0017Y@Zc\u0005HT['\t\u000f MTu2\u001b~!5JGR^\u0006'e\u001065{ʀ\"W'5OL\u0014BEnjHh\u0018}\u0001^AcGW\u0003\u0000\r2Ǎ\u001b\bhS\u0002\u0016H6{\r>\u0013\u0004~\u0017)\u0003i5U+!|\u0019\u0005=\bvΡ\\\"W.)\u001e-\u0010ɒ\u000ey\fAcݕ\u0004j J\bf{^G{WZL+ev\u0006\u000bEY\u0019XЊ*#\u0002E\rA/ęuƞ\u0011\u001e%]X\u0017\u001fo\u001aV\u001bd\"v\rK|\u000e:Ա>SlUg\u001a:=rxfc1-:yRߏ\u0012i\u001b1E;:!o\fȕ\u001d(U\u001f\"\u0018\bv\u0001`&\u0011oQ\u0011\u0016#\u0019+B]j\u001b!Vz\u0006\u000ffz!p`\f=25\u00138a!$j8\"o?f9>D\u0011EJ\u001cE(Pg\u000e'B8`$tR\f)\\⥽QF6\u0006M\u0013\u001f\u0001r\t!B\u0001#YAv,׏\u0013_\u001ekk\u001fuk?AfU!q\u0000RḘ\u0016|㱱5\u0003찪JLi>:\u001b9\u0005s\n/\u0013v(|=gnOd(.qN$\u001a\u001ax\u001djm\u0015SW)̎\u001d5jT\u0016\u0011KI:<3^v\u0006\u0007^U!2w7\u0005f]\u001f}ݰνA~M4쒭\fNZ{e3>b@Nݳg w)3l\u0005\u0007u@23\u0003Fj!\b\u000f\u0017\u0011~\u0002\f\u0000<e\r\nendstream\rendobj\r22 0 obj\r<</BitsPerComponent 8/ColorSpace 23 0 R/Filter[/ASCII85Decode/FlateDecode]/Height 23/Length 228/Width 23>>stream\r\n8;V_Vd1+#:#_lhU!caSg'i,jiJb5p7\\B]X,dIci`%;l(Aq118L01&:,0,cSE[\\l?L\njE*gpfUHdLGgQ!=8c'!DB7&!>;TsN(6o9+Oaos7rTuAUD6q\\+!>[5tSd9RG7R94@0\nDp*Ss#!u#Oh+h*d,RE*e_klX+RG'@fRT7%'-E0NM?+nIoR.`#)1ZPG)h35SoV!kZl\n]M2*;a\\S?O`JC@'jKi1ZB)iJ=4'q~>\r\nendstream\rendobj\r23 0 obj\r[/Indexed/DeviceRGB 255 24 0 R]\rendobj\r24 0 obj\r<</Filter[/ASCII85Decode/FlateDecode]/Length 428>>stream\r\n8;X]O>EqN@%''O_@%e@?J;%+8(9e>X=MR6S?i^YgA3=].HDXF.R$lIL@\"pJ+EP(%0\nb]6ajmNZn*!='OQZeQ^Y*,=]?C.B+\\Ulg9dhD*\"iC[;*=3`oP1[!S^)?1)IZ4dup`\nE1r!/,*0[*9.aFIR2&b-C#s<Xl5FH@[<=!#6V)uDBXnIr.F>oRZ7Dl%MLY\\.?d>Mn\n6%Q2oYfNRF$$+ON<+]RUJmC0I<jlL.oXisZ;SYU[/7#<&37rclQKqeJe#,UF7Rgb1\nVNWFKf>nDZ4OTs0S!saG>GGKUlQ*Q?45:CI&4J'_2j<etJICj7e7nPMb=O6S7UOH<\nPO7r\\I.Hu&e0d&E<.')fERr/l+*W,)q^D*ai5<uuLX.7g/>$XKrcYp0n+Xl_nU*O(\nl[$6Nn+Z_Nq0]s7hs]`XX1nZ8&94a\\~>\r\nendstream\rendobj\r18 0 obj\r<</Intent 25 0 R/Name(Layer 1)/Type/OCG/Usage 26 0 R>>\rendobj\r25 0 obj\r[/View/Design]\rendobj\r26 0 obj\r<</CreatorInfo<</Creator(Adobe Illustrator 26.5)/Subtype/Artwork>>>>\rendobj\r21 0 obj\r<</AIS false/BM/Normal/CA 1.0/OP false/OPM 1/SA true/SMask/None/Type/ExtGState/ca 1.0/op false>>\rendobj\r7 0 obj\r<</LastModified(D:20221115174608-04'00')/Private 14 0 R>>\rendobj\r14 0 obj\r<</AIMetaData 15 0 R/AIPrivateData1 16 0 R/ContainerVersion 12/CreatorVersion 26/RoundtripStreamType 2/RoundtripVersion 24>>\rendobj\r15 0 obj\r<</Length 1477>>stream\r\n%!PS-Adobe-3.0 \r\n%%Creator: Adobe Illustrator(R) 24.0\r\n%%AI8_CreatorVersion: 26.5.1\r\n%%For: (KIRKLAND) ()\r\n%%Title: (connect-query.ai)\r\n%%CreationDate: 11/15/2022 5:46 PM\r\n%%Canvassize: 16383\r\n%%BoundingBox: 0 10 191 180\r\n%%HiResBoundingBox: 0.000004398789315 10.0000007744293 190.00000001085 179.99999970249\r\n%%DocumentProcessColors: Cyan Magenta Yellow Black\r\n%AI5_FileFormat 14.0\r\n%AI12_BuildNumber: 228\r\n%AI3_ColorUsage: Color\r\n%AI7_ImageSettings: 0\r\n%%RGBProcessColor: 0 0 0 ([Registration])\r\n%AI3_Cropmarks: 0 0 190 190\r\n%AI3_TemplateBox: 95.5 94.5 95.5 94.5\r\n%AI3_TileBox: -211 -301 401 491\r\n%AI3_DocumentPreview: None\r\n%AI5_ArtSize: 14400 14400\r\n%AI5_RulerUnits: 6\r\n%AI24_LargeCanvasScale: 1\r\n%AI9_ColorModel: 1\r\n%AI5_ArtFlags: 0 0 0 1 0 0 1 0 0\r\n%AI5_TargetResolution: 800\r\n%AI5_NumLayers: 1\r\n%AI17_Begin_Content_if_version_gt:24 4\r\n%AI10_OpenToVie: -184.931677018638 417 1.11805555555556 0 8220.98136645962 8147.60869565217 2117 1873 18 0 0 227 219 0 0 0 1 1 0 1 1 0 1\r\n%AI17_Alternate_Content\r\n%AI9_OpenToView: -184.931677018638 417 1.11805555555556 2117 1873 18 0 0 227 219 0 0 0 1 1 0 1 1 0 1\r\n%AI17_End_Versioned_Content\r\n%AI5_OpenViewLayers: 7\r\n%AI17_Begin_Content_if_version_gt:24 4\r\n%AI17_Alternate_Content\r\n%AI17_End_Versioned_Content\r\n%%PageOrigin:-864 -446\r\n%AI7_GridSettings: 72 8 72 8 1 0 0.800000011920929 0.800000011920929 0.800000011920929 0.899999976158142 0.899999976158142 0.899999976158142\r\n%AI9_Flatten: 1\r\n%AI12_CMSettings: 00.MS\r\n%%EndComments\r\n\r\nendstream\rendobj\r16 0 obj\r<</Length 38915>>stream\r\n%AI24_ZStandard_Data(/\u0000X,=\u0003$á(DD\u000f\u0000c:,\u001a\u0006@A\u0015QFRk<\u0000\u0000\u0000\u0000A\u0000\u0000@\t&\n-\n\u001d1䷃p\u001f\u000bo\u001f\u000bM\u0019^X>\fկ÷W~w\u0001o\u0019Yj`C\u00031ʬY-\u0016[=m\u0019~53\u000eT1E\u0000><b}m-\u0003\u001fávnQ\u0017?fk;\u0002-uG \u000f~qG w\u0004\u000boY]la͗8[^zv\u0003Z~c\u0016\rl\u001eoo|(\u001d\r\u0014؞eaQ'\u001d)._\u0019t\u0016ݢ:lv\f\u0000܊խQ6Ѧ;-oU\u001bG_\u0019f/6\rǭ\u0016PX4k.\\{ɭ>k`=k@+[mz\u001ei\u0001\u0003n{`=ֿexZ=\u001emzu\u001ak\u000e\u0000k7չ\f\n?G\u001ebp\u0005t\u0013c\u000eƏiE,y]c|\u001f౦iVۖa]#k.\u0003\u0018kn}:v\u001fOZ\u001a\u00009FktzcXǷ3nf\u0005]Ǭ5\u0017\u0004\u00187ytխ/\u0017X,ztխ׏k0~G\\0d^\u001ee3\u0018c\\r5Z7~\u001emz7\u001c\u000b~~t\u001aokH\u000b8\u0007H\u000bh6\r;\u0002b+Ѯ]5I`\u001dw\u0004o\u001dB;\u0002pYc8F_\u0019r;R\u001f~\u001fk\u0007c\u0015&\u001f4|5\u000f,j\u0007\u000b;]ǽEu\u0000\u00187dzn\u000fAZc\u001bZ-eg&~[s5[?\b ,_?S$\u0001k\n\u00182\u0004\u0013w\u0004|΢\u001dDf38~gڎz\b.F\\vW;Z\u0002Y-\"`pn\u0018\f\u0015^\u00052\u0015Ubj5Xe\u0019ƴ\rw\u001fԻj[<lϟ9\u0014O\u001dv\u001cޯ,\u001d5`\u0000\u0001\u000b\"\u0017\u0005\u0007[um\u0006\u001df\u001fT\u0001<ˮ/kA}6v!v\u0006Pٲ\u0001\fx&~\u001fӳ~@\u0001\u001bற_f17\u0000Xb8R|,3\u0001`\u0007yZ%Ukd4%rn\u0005\"Cf55\u0004w4N\u0007\u0006~\u0005P>7ӭ\rZkQe`\u0007\u0006\u001d\u0002OY5\u0018g\u0018\u0004񧔵\u0012ǟ\u001an-my`8xg0^?cv_g\u0000\\~8\ft\u0003\u000fP-㷃o]/=)ڑg\u0018Nh8nug\u0019ߏ}s{U\u0003eu\u0001\u00145lo2\u001cߵ?_s݉\u0018ɶMf]XTYa[o{-mxp\u0000\u001f\u001e5L\u0007\t.Rvít}g,\\ƂIo8\u001a'=\u001c|f\u0000\u0000lw.u\u0003Z_ږ?fu~نcלg~\u0001\u0000Ow)}ÛuwmfYz`\u0017\u0016k]9[~g]ây.\u0018\fA\u0003n8Y\rܲp̆wTs\u0000r6\u0013Cv\u0013;ĀoY]ϴ\u0000[\nv\u0001+݂\u001f\u001d6YMp1l\\q\u001b\u0007\u0012o\u0001^%\u001b*u\u001b)usu\u001cEi:޻\u0000\u0015tt|\u0006:qj]_8\u001d#\u001c8X8Ln6Lsqv7\u001dX;\u0017\u000ea2\u0016f\f\u0018}:qoo\u001c?g08wCv\b\u001d_\t{tr\u0000!7\u001btתs;}:q\bp\\2j\u001djs#\u0011w՜W~5Bqm\u000f\u0000\u0005ۙp<f\u0003@?\u0000][VZoG:ħ\u0018sɵk.\u0019~\u0013s(P\u0017kk1ap\u001c72fW~c\u0005gb\r\u0000T7b;v\u0000]\u0017GCd֡\u000e\u0010w\u00178\u0003\u0000G\u001c\u00002;_\u00114`~-qKеve\u0018V;f`2|pݑI\u000f\\wd\u0018[Lqm\u001cH3r[o\u0017\f;w\u0018\u001bgU1\u0016ECa\u0018\\s>|\u0000><:]_\u0000\u001c~߱btG\u001dFJFw}\\E/F\u001b_8Ns({1r\u001b\u001d\u0016'o>ͮQ.\u001a3\u0018^:F\u0015ã9$La\u0000\u00173E%ð?Q1]\u0001ofV4Z<sXTg6Y\u001e?~[\u000fߌa߰,\\pnVUM\b\u0001~w]fyz\u0018>Gѝ\u001bӳ\u001fRqGe;\u001ag\u0018\u000f\u0001Ȼt\u000f\u001b&A\u001f,*F\u0016ʆݣYmDE1ܪNmƓ.9{o^M'\u0003(îxou֚891:\u0018;\u001bsGJ7M\u0006쥣h8Jsh\u000f\\i;z{ǻy\u0002a\\'߷qe\\\u0001\u0000\u001b@~5na>{ɳw<\b\u001d\u0007ԿFSܭ/s\u000b\u001e?m\u001c\u0002\u0010F`>\u0016\f=9.|gخHհ߷q|4}|muz_So:>Ϛ]\u0002hG\u0012~%\u0019:~%H\bLΆ\u000e*i\\k;Ʉ\u000f\u0013\u001f\u0004\nR\u0005`Ö<7\u0018B~\u000el\u0002)j\u000b\u001a \u0002W\u001a\u001c@2Yiî\u001d\nw`ի9g\u0012\"]d2gOKo:\u000fO\u0013ߪC\f9PZLG\u0001v`\rځĐZ&STZplEXU(vc\u001ctP\u000f\u0002!\ryh,<,\u000buR-$n7\u0012bf9QSu1R^\u0019\fP,f(fJ\u0013O\u0014H!G1\u001c<e\u0004\u001f/^*JRrǫU*\u0017\\\u0018b_AN.J*J \u0019\u0018W8/D\\(ƍNl9'Sh\u0017/i~Ds\u001e$8\u0011}(C\u001dyJ@E%C&:Ş'a(\u00112sڣL\u0002wS\f.N\u0001Qu\\t-\u00124\n)\u0004\u0007\u0017??\u0018\u001as~\"yH04\u0006y`\u000e\f<$G\u0013by\u0012z.hBY\u0006/39\neYt\u001c0]r]0]r!eBYlbd\u0002ׁZH\u0007\u0016P,7`XPz.\u001aZy2l=\f.N!\u0018)/^ hFo4\u0018\u0006\fKʧ@+M\u0006ۋ&bϓ8\u001bkƊU&\u0017\r]{|\u001b'f\u001d#\u0007_p\\ׇsh\u001a*%\u000b\rݍ\t\"\u0007qvC]W!ErQ\u000fu\u0019ð$l\tHb\u0017P++dE9FʡvZ\\Ko\u001b\u0010\u0012lj\u001eh\u001aΏp=\u0006\t$%r\u001d*L\"+Ȗl\u0018i-'dSc`\u0001ⴓ=O\u0014`,R'\b\u0003[yE1\u001a\u001bgᒃ\u00175?T\u0015\u0011Y\u001coX\u0011e\u001eOϰu+?FNy\u0012z:&\u0011?\u0016ECO\t2Iξ\u0007\u0017_\t\\\u0007Z8P8A\u0014dpqJBA\tZ\u000f$\fTOjOD3vrJlFXȳZj\u001a \u001c?@\u0019=\u0018\u0003oF+5v`Lq)?\u0014\b\rwG\n ӄ]YV\u001a\b6`p&m\\\u0001dZK7v`\u000fL\u0016\u0011\b\u000b\u000f\u000b\rqUف\bV\u0004&\t\u0002L9\u001a\u0006\u0002u]+EH~\u001b\u001a\u0003ҰP\u0012vD\u000e~P4\u0005g\u0015=g\u0015ǂ\nbgr\\\u0014\u001eE^\u0015s5z\u0018Jyn}͸\u001b\u0010aVf\u0012L\u0007~&\u0012.d͉\u0000F\rh&}*G\r[L\u000f6b 0e/44\u00163btiD\t+ل#4\u0012\u000eH6]xלi)\b\u0017]\u0000KU_Dvi\u0011\u00011xc2'7$۸g%IyY(ϐ_\u001b\u0005~qc8S\u000fkCɠlNx&\u0003s t\u001bqGզ\u0017\u0001B*݆M\u0001U\u0006ٜƍa_|Tlj2R\u0015Ļ\u0007=\u000f$Y\u001aM,\u0006m\\\u0006Ē[\u001fjwB<h\u00156\u0018\\<-)\u001a\u0018\fl\u0001GۓCPm\\\u0010vf\u001f<2TB`-\u00158\u001bD\u00142\u0004\"Aq\u0004nZ\u0014/  ݪJ\u0015y'R%!NiARW\b!(R\u0000e\u0004\nd\u0006qiI8ƽ\u0007D\u0001\u001b\u000bA쒮x\f\u0000\u0002gF\r\u0017\u000b\u0006\u00112aĿ4OOɥr@^\u001cV\u0006\"Q\u001c\u0011\u0016\u000bsR`\t\u0017\u000b \u0003\u0011\u0004Jd)aaq\u001bkuB\u0011,4۸ cش\u000e\nèJd\t2<\u001d0%\f6N2NH\u0001-\u001a27\u0016d028\u0013\u0003\u0007u\u001c!3\u0013\\Ј}\u0010\u001by<8?\u0014j9>\u0005\u0006\u001d؜Ť\u0003&&z2\u0006j4\u0002aa\u0004$4\u0016]\u001atQ;\u0015.\u001fӷqǍ\u0007N2~G\t\r\u001eaaXD_Ͽ}\nW` #\u0007\"f@ml\u001a\\\u001cE \u0001\u0011__@Ir\r\u0005\tK\b\f({\f]ic!\u0013M#\u0004;񬣰Ja)oj\"bOxw1xD mEG\b_(Y*\tI\\J%g\u0013\u000fB\u0000#\bzң\":5*|yiЉ{>\u0001Ԗ5p\u0003MC\u0006ڰ\u0014\b_s7n/il_d'Ϊ5á\u001107<\tC.F\r#S3DxiZ\u0019\u001azI%6\u0002\b3BOzumgF\u001c1Y<9\"\u001bUu\b%}A҈~\u001eB\u001aHYy` ςYI\u0019M&_\t\u0005\u001a6Vơ+,'\u0007VK\u000bO\u0011;6j\u000f\fgy\u0012&\b\n]N4TB*JR\f\u00037\tA,㬨\u001dXi,+>AFW/\u0005\u001a.5o\u0001DY\u0005s5\u001b~o\u0003_y)/^=wo<\bw\f5pE\u0005E\u0001\u0019f\u0012HL\u000e\u000eM\u0007\u0010d\u0013\u0012\u001bqC+GQh(*\u000eO\u0016N!r\b8mCf̵\u0017տ\u000fu_lʛL\u0010XͬX 稉7!TdNxʇG\u001d&$9\u001aIBD5z6,\u0016\nH%Gq\u001fݢBbK\u000bx[ w\u0004rkܾ;\u0002ݷ<\b@];`\u0007}}G\u00000\u0019-2\u000f{gY5fs\u0000w溵):֚Y-˚zeq3U.A4\\쿎r\u0000,k\r۵.~UtZ5k1M]\u0007qo1w_jzD\u0017\u0006\u001bvN;6\u000f-v\r\ti\u0001\u000b\b\u0002\u000f\u0007F*J«\u000f\u0003wqD5ḰTxaQ=\u0014\u00156ըmD\u000b>l\u000f1B\u001an_װ|\u001bk\u0002-\u0001SzfV\u0004\u000f\f6&M謨\u0018M\u0019ЄĂzt}:B+PF-y8\u0005\t`\u0015\u0018@B:S\u0018\f!4I1\u0015U=(CX\t\u000em\nA~\u001bm'_o㾍\u0007,#D\f5\u0014ud%\u001fVu*%JUᡥ@\u0017=\u001ac#0\u0019&z\u0002\u0003\u0000xP\u0004薓QpK\tݐ\b\u0011\u0018lV@\u0007\u00058sğȥo\n4,᡾ZeA\rao\f\bɷq,9ԫϸb'HP<\u0011kx\f\rV<Cc\u0018\u0014\r'N\u0012\b/M\u0011\u0007*iDVB\u000f#CC/s \u0015\u001e=)<?I 6\u0017\ntlc`\u0016\u001fK6\u0012`}Ck2%!\tScv\u00036:ѐ\u0016(!*ɫka$B\u0014^|Y=h|\u001bg\u001f\u0018z\u000f\tBo<We!1Օ9\u000e60e\u0014!o t\r8TJ)\u001f'\u001aH\u000b\u0005o!b\t\u0013tb{-1rukJ;\u0016L9\u0016RP5\u000bCtZToHr,3RSN4!\u0013JʿJW]\u0017G,ht*[2niL#4msIkI&\u0017Hٵ<>S+x}\\dm\u0013\u0010)Vٰķq7%v25\u001c4EH&T\b\u0003\u0006R/\u000b\u0002\n\u0016@Bs\u0018+&2v霞X\u0000\u0001\rAM\u0013i\u001aRe\u0011];\u0005\fb@!\u0012\u000f\b&g\u001f' ,\u001aecR\"TT\u0013\u0018WC'_m\\PCÁ#S\u001b5Nz6<*\u000ew*Gv\u001duZ8DW\u0010T$/6p\r}̧Bcļ\u001aHՎ\u000f6&Bjl\u0000\u000eY *\u001cb4$ZPt\u0002/aT;3t!C\u0018*\u0003ʳ?\u00165f\u0004`\u001cP\u0011UmX^V\bfy!aUA]\u0017L\u0011+f\u0004݄G9ND\u0014VT\b\u0017\u0014)8Z$8ZC\u000f,'u6<6j2\u0011XTt\u000eM\u0007`$\u0015(n\u0010#6.4jA&!IgaƧI'\\JYO\u0013ϓXw@F\u0019(~\u000eU\u0011=&=UKrM#\u00124t\u00101I\u000e6T:Tl\u001a\u0012XqZ<\u0003-_=?\u0014\u0005,<bHh&\n/S\u0010\u0013=umjT;Қv_3ED\u0010\\b]@$pFN^\bL9B]\u0005,˿\u001b8B\bC:m\"E-]U]\f\u000b_ZO0R \u001c`KS@!\u0011OI@\u0010Y,\u0004oe ِBNPdP@a>Aj\"TR\u0011PЀ\\\u00123Yn\u00113ZMe'$\u001f\u001aGc@\u001am\\\b=yIFP7\n&\u0007L\u0001&D\u001e\u0007*FK.MEz2G\u000b)x'R\u0010%fL\rFq[~\u001b\u0007J0VYJˤ>$Faiuer\u0003=PAs\bM(\u0014\nfZ5Z\"\u0007O\u0010b\"\u0007O)*\u0017\u0015E\u000eB!\u0019\u001d\u0017/\u00075诒vr)\u0007/\u000e//\u000e/vx&\u00171\u001aPfC9P\u0006%~/\u001c\u0005:ά㢠RdU\u0014psU\u00149\bd|\"Iy\u001e\u0012\f$yH0Ю\u0003%x\u001e\u0012\u0013Iʻ4G]2s\u0014uQ(1]r\r\u001e\u0015X\u0015\u001c@Q[\nNUi+FoK\u001d$w\ri}O&h7s23/\u000e>8tD7tp%\u0019:'Sj/\u0019|\u0002U4lE\u0017}P*\u0006K;\u0010=\u0001тp\u001e}Y#RUP-v`L& ع\u0011Őz\u001a@]W\u001avOM\b\u000bb*R0e\u0002\u000b\\8؜4@O@6GPDSTPC\t/R\u001e(5\u0012=g\u0015\u000e$E\u0012G\u000bb\u000e3\u0017\u0002+oq\u0013\u000ejCPth\u001a)/~#MXRN\u0013D*\u0019XS(\u001d\u0017XOlP\u000e/N\\D!A;PfQ!&d<*瑋J\u00014:O$)K\u0006'`h!x\u001e\u0012\fM\bE\u0012.&Q(ڥ_f\u00172>\n%KKyhh]!\u0002\u001b;x;-hĦ\u0016MI\u0016Ml|\rQ\u0013ݦtDtd\u001cLS=?BXqN)HV+\ne\bi|*\u0001]\u0014\\in̯#i\u0017auL \u0001\u001160\u000e?;\r'PF \u001a %\u000eN&\u0014(\u0010\u0016\u0004oyjq%@+dӰ\u000fu\u001e=:n(Y\u0017j@d\u0005]>a%]\tP8U$UMQ;2^\u0004/FD\u001d{4PF\u000fI\u000bfZCj\u001cދ(NX\u001e\f3EhlYnI\u0017Ywi)ć6M&\nSi\u0015/j֪Zv\u0001N.\nGRI;h\u0017ëM\u0013@OlN\u0011\u0019dٟ<r\u001fjS\u0010!T\nJ\bĪ\u0015b\u0000\u0011\n[:㢠R\"Dx\u001e%&/4G%\u0019h>\nev\u0001\u001f2]ܫ^A\tR\u0013\b\u0003\u000bJ,\u0005b)`6+(1UIW&_y\u0005fܟ:\u0002\u0013KG\u001f\"\u0007?r>O)\u00159!\u0015;\f\u000eT<\u0019},6\u0015)\u0003N&6E8ΦX6\u0015̪V\u001b\u00163\u0003taP\u0018FU\u000bQ\u000bL!Cba~\u001bW诏:'X\u0017HA\u0019[\b:3\u0019\t\u0002\u000bFW;\u001e6\u0014rgV\u0019[2!1\u0002\u001f\t\u0019'\u000f\u0006L.\u00146\u0016\u0015Ӹ(\u0002Q.>2TH)xg1u\u0004),RK!\u0011:D\u00192VLUaշt>˾>.9R\u0013|\u001b'y 2&\u0005aUG\u0019[FF\u0002X\f:\u0015Z\u0015Vf\ry\u0011 hu\u0014pxIɪȾD\nm\\ɢv`=<S+Z\u000e>C\u001a\u0017Ce\tGڭ[YCf\u001a\fV\u0004dZaUĞ\u001d\u0011ySbR\u001e\u001a5^+\u0004\u001e\u001d\u0018^#?ٕS\u0016.#XhLU\u0019!ͨzqBKk\u000eCR-DA\u001e^AD\u001f< \u0003O\nbw\u0000\u0015\u0016\u0013R0bQ3ݐc.G[^Lƥ\u0015N@\u0005EV[! aI\u0013\u0015q!5TN\rytyx\u0006V7\u001bUT*o㾍;(1&SNp>R5+\u001aBҬ&)0\u000e/qL8meb\n4\rI#HQ\fut7D\u0003\fZpF/\u00156\u0000\fK\u000be\rUЖi)\u0005z\u000eW8Ƶ;\u0002\u0002fJVbT\u0014-\u000f\u0019VTM!\u0006Buo\u0014\u0017>7\u0004b\rf\u0000rb\u00121\u0012\bh^TF}\u0011\u0006O?\u0018Vs\n!ChLrL\u001f\u0010/\\VInvv\"Ɖ\u001d-\u001aqh\u0000/>M,\u001b\u0015xԬ8\u00123LqAlb 2GD-\u0019\u001ds\"̈b;@\u001f ⣩4񠉒܀l\u0012u#$\"FDDCQf\u000eVN4\u001cU/KT\u0013]\u0011Q^\u0004E\u000e>9@\u001a\\\u001fZ\u0016\u0013\rнp2Oj5\u0003ňm\u001c\u0004E$}\u0005w&9v\u001aK7\u001bF<ᴋ\u0018HiV^UzoJ\fH\u000e\u0011Ȓ䊏t/䳷8Pb\u0011xEX\"aU\n\u000e5_\u0013A\u0015#|۸^2eYCni\\\u0010Q\u001d\u0019Ou\u0005&+Њ\u000e2a\u0010xU1ʘH>\u001b\r0ta)\u0003iȒC&D\u001d$C3x{#m'ڎV`|x*M|B4hqEKD%y0H$-\u0012+(\u0011J!\b\u0006\nGq\u0010*'\u001a*+h\u0018\u000e/^90\u000b@99\u000ed(\f&v\u001a4wNTjI\u000eD\u0011̼x*A0gf\u0005R*EE\u001d\u0018S5;ZکŹ6.Fѯ*\\/O\u000e)Y)$)J'AR0&,EQ\\U8G\"JDuĪQm\\XUxb\t|S`\u0004I͒We\u001cF\nJf\u001aERHܟk*k!A\u0013^\u0005Ή\n\u0006#rb\u0010\u0013@`WsQ>\u0010f]\u000f>ơ\u000eUV٧\u0013\rK\u001aG\u0004\u0010CI)\u0000.#\u000bV;\u0012y\u000e>o9J49@J\nE=@\fӐ>vH^Dv(UيR\u00191АܜhH>h+6'\u001a*Ɣۿ$\"nsPYr\n-v̉\u0012\f\u0005%9\u00139x0E\"\u0004f%s\u001b\rẢ\u001fCVN4\u001c\u0018Sn\u001fiBVN4ğJ8\u0011IG{(\u0000&PV;!4rvRYdکc䢙ozLpBF`[w~\u001auMg\r8]7+$\u0017у4\u0002#Q\u001bJ\f\u0001Bծ\u0004\u0004\nHXU$o4l\"\u001aJ1V4a\u001aQ'\u001a$\u0013\u001arԉ0#D?C\u0014!\u001f(@Fr\u0007Mb\u000bu忍+\u0007_y>@\u000eT\u0003'\u001a.f\u0010$h8$,I3\u0013\r\u0011(\u0016\u001ar\u0012I:ѐxV \u0018՛2e\"y\u000fh;\u0001\u0016.@*1rsH#V\u0010~BI\t\u0018O>T\u0013\r\u0015\u0002\u000b\t\u0002\u00044,EDÆED\u001eQD#\u000fF%zN4\u001cC\u0018saTzߜhXJZen\u00117,P؜hM܎9\u0010FH)00\u0013\u0003Q\u000ebʉ\rg[\u001d)'k\u00189IN[\u0006o?\u0010V\u0015`$\u0007a<oՉ#x6\u0018wpE\"aJiĆƩH\u0014\u0016\u0015T\u001a.*g\u0006 2%\u001d\u0019B\\6\u000e\\͢qQoJ\u001dXkoV̈{\u001b7eҷa+\u0005z2k\rf|:i\u0005#$!\u0011IJ!V@ǕƀB$}\u001b'&L\u0011\n^\u001c[a\u0004\u0015mV-V47\b\nbw\u001f`\u001c\u0015@qm'%A<fN8\n;\u00037J9P\u0013\nʷq\u0019\u000e³|\u001bW*\u001dHEƥ\u00122\u0011C\"\bm\u001c\u001f{4\u001c͸\u001b\u0014\u0015O\u0010!\u0014QI\u001e}\u001bW#w\u00186۸]8+E&ST\b\n#g\u0016o2f5U|T\u0004+S}RnYCZ`\u00177\t-\r%\u0016*jl8\u001a\u0015a!\u0015k\u0007^J\bh!f\u00120-*Q\\|QӨ\u0015\u000b8\u000f9X\u0014HVGE4j2щ8҇+N\u001c\u0015\u000fVe\u0017BKc\u001fʐo㾍c\u0006dJBvvr{Ec*\n*\u0003d=Ke\u001b4q\u0018!+0\nߏJ~\n\nڒ\f%wK\"'%bH(WpŃR#\u0014\u0007\u0001\u001ci/Q\u0011n\u0013\u000bXm\u0013Lժ& \u0002QH=%>ŷqAG&\u0010\" dG1b\u001f\u0006[ttT\u0014B\u0001\u0011\u0019\u0019\u0000\u0000\u0012\u0000 \u0018\u0018\u0016\u0011\tF\u0003:\u0003\u0014\u0000\u0003>4(T<P,0$$#ah\u001c\u0012\u00038\u0010\u0003)\nPTRIW\u0000EBj-D+',ا'$5\u001bD \b%H\u001bfpGll8\u0016VxM֕\u0011S}.\n\u0015sP8#\"Aċ\u0006X<&K\u0010\u00005\n\u0007\u001a:\u0002O\\Rŗ)ʉ\u0003~5Z\u001aمeTZ|fE_o&m+Ɇ`^\b\r$Kr\u0015kj 1,L\u0005[M\u0017:wb\t\u000bG\"\u0000P\u0002Vx\u001e\b=\u0015pF\u0011^_W?}mv\u0017\u0002\u0006Zd\u0006+p\b(\u0016n30N辰ߴ\u0002I2w\u0012H7\u000f|K\t\u0015\\<)'\u0018\u001c\u0007\u001c{kţUin*DER\b\u0019r\u0017i!n\u001anInEXUT,I\u0006[?L޹h7GI\u0017\u0010(Jw}ɠ6YܠsU\u0002\u0007.7d\u0011c9\u000el)\u0013\u0000lD2\u0012Anڣu｀tD#\u0000\u000bVma\u000f\"T͉m\"HmNn9':|2B\r\b\t\u0000[+Et\u0005?\u0012v\fM \"iԚ(ē\u00176YgWܫ21\u0016IO¨\u0018i\u0016>Olhĭ)԰YGL\u00156.ٟMt5ȥ\t3*qR%4M\\\u001d\u000e%!\u0004Ȥ-|292C!Bj{V}^ٲ-\"eօ\u0007\t\u001a(xbB\u0003f:>]ֹ\u0000\u001bfJ`A\u0016ªYW=!V\u0002\\5XE߄!?ȉ']\u000fT\u0003\\/^\u0010d\u001fx`\u001b J|5\u001fV=hh2n\u0012-ۼرR\t`\u0003{>[\u001fP\u0012\u001aO8v\u0005&0F\u0013?\u0001 1k^<$)\u0012ɱ\u000eZ\u0016+Nt\u0005\u0014aR\u0014lpʢ\u0017@Wt/^Ļ/\u0004(\u001a_n#oqs\u001dI_\u0005H\u0011X\u000elp,tM\u00140\ru\u001eeK\u0015\u0005DWum$C7]c3FaF\b=\"Ùh?\u0017\u0018}\u0010SԸ$\u0013RhT\u0004\u0002&\r^\u0007\u0006\u0015\u0004p\u0016oqh\u0015T\u0017\t *\u0001j|\u001bgaRɚyUA\u0006mI\u000e:\u0019LK%\u0016eJ`\u0004b9\u0014r0X+4\u0013Z6\b\u0003&\u001c\u0003Oo\u0004\u0017X:%\bPJm,֪E\"%Q<,[Խǅ#2C\"\r4:x\b8\u0002M.|\u0015H;\u0006Ţ^7+!c-nR8{Q#%Q|sЬ6T\u0010୦\u0012('!\u0007k\u0010jVjj6k`O\u001b`\\\nD{~3V\u001eWf}vy\u0007#&PUA_\u001agZݴ\u0006TxzԶ!bmp._B2S%\u0011HKī~dcr,o\u001a:Y'eZd\u001eV\"\u0011qK^\t\tڎ{\u0002~:c~YW4m!\u0016\u00165WY\u0000H_cKa6I4{a.=m-\u001f\u0002\fjFm-t\u0017].\u0005^^\u0005\u0016!,c:l^o1&\r%YlHV\u000e[?.n5'̴R\u0012nZ `,\u0001;\u0002iD:.h\u0006v#nh\u001dЍU\u0004gbhUdV}'\u0015\u0011g,ߌ\u0019Q\u000b~;Vk\u0000\u000f;fM*-{Z\u001a\u0003M\u000b]$}hHL8ϳC\u0017c?a(yU\\O]4!}\u000f˅\t\"lk\u001dvՠ'pйtR'Nܺ\u000f\u0013QnS\u000b\u001f4ݦCJ67hD\nA\u0014\u0015\u0012\n)\b\u000bvr7a@\u0013n\u001d>{Xx\"n\u0013c'zBѬ\u001d\u0003\u0013\u0005\u000ftӎXr0B\b<!ɹ\n|ĔMP|I~0*3$K\b\u0000Q4:ؖ#M\u0010,&1(`r\u001aqa\bW(\u0014MZ='J'R\u0012\u001ep6jmȊ|HȎѽ@\u0000+s#z~ d\u0006j\u0016\u0014O\u00111]:\tG8\u001fy|\u0002<\"`{=5&#\u0013F1{\u0013Cx%3s<ؕ}n(W6Ar\u0014\fӓ6ͭ<[\u000eg\"\u001dhDzu\u000bOWҿ*C~c3\u0006KA~<\u000f\t\u001f\r0L2\u0007n |!ihX\u0018pw\u0003!KO! 82Ǚ\f}*sJ7*\u0005,r/kfB\u0005o\u0003L\rQv498\u0004\u0010N\u0007d!\u001b\rv1&sa\b17\u0014\\M/\n$@c\u0016\u001d_\u000eSܲ#mݴ֥)\u0012\u000bhmr,z\u0015X`2\u000b˃To{q\u0010%?\u000faix\u0007`^^\ti\"^LST\u0013\ru\u00067\u0012м\"\u001cbEY6o8X\u0017>\nu!/7\u0019N\u0019zO/\u0011;\u0004}с-\u0016-C/\u0015\u00104\u000bnՖ<]dN1\rczQH\u000e`QAL\u00175MЀ\t1{\u001f5ČJB\u000e\u0004B\u0000Kh\u0014f#n\u001b]\f\u0001RX(X~@\u0000WVF\u0012/|o`ۛ\u000bPp%W\u0005A\u001f\u0015X\u00030R\u0003t-\u001fuyO^L\u000effg܆Aqv.\u000fMR64\u001bR\u0012NLq̆գ\u0004 xBY̎\u0002\rICG\rt\u001eeH%1E\u0002HXƽlmV٪xhr2\u001bjK\u00134YHdpzd\u001db'\u00054\u001a@Mb|bqN\u0000\u0006\u001f'D\u0006\u0016祹&Ц\u0003T@'n\u0016ch\u00103\u001cCeyV\u0000w ܯ7;V\u001d\u001aTISiJ\u0002Ј^Ή\u0002}o6hG\u0001V\",<gZ3,isA5\u001e@\u001fٵln󦝫x -\u001baK\u0002lY\u0006<pfz3L-\u0016q\u000e7\u000bA=\u0017Sȧ;*\u001aL\u0005\u0007(Xtp\u001f.\u0006΁ua,? \u001b\r\u0006k \u001e[wh!o\b-\u0017n0}y:}\"VK׌Us\\[;!ցڍ<0\u000eqq#z\"\u0005\u0002!\u0002}ɇwrr\u0016N\u0013\u0010i\u0004p\u0012Lx\u000bHϤel\u00103CHJy\u0012L3\b)At2\u0012qx\bcMDQn&\n?\u0014OO]7\u000fg>]\u000bƐE+{Rr#7uCU)ew7(TO\u00173M7\u001c)v\u0017\u001dSHg\\Dń\noh'L*\\ܟ8H9/Rҩ\u0015WϠWe\u001e~dl\u0010)Yͼ^-\u0003Dko*\u0000=GL^\u0011IU\fy/ӟ\u0017l\u0000E6\u0016ZSr`\u0011ncdXt媸6!()OJm $m.2A,`_9*\u001b\tļ67\u0010'}^-4ȖR@\u0003\r:\u0015\u0004q#7Q2r,m^y?jf0֚Y\u001b;ߢ4iBCr$Bi48\u000e\u0013tH$9{C\u0017u6g6\b5AN%9\u000eS$4Lz\\>u\u001f7ϵB?I\u0006Ө\u0017$_L\u0010?O7<ˁ$7\u0015<'UҰ/3x\t\u0006=OBާY$BJv\u000b(֍]`pIgz2\t\u001dIObO\u001c\u0011y*u\u0016\u0010Vk%e{C@UZ7}\u0018<Y\u000fW\u000e#B9ZT\u00165\u0000\\;}Qs\u001f1լ h1\b\u0007JN\u001cgwz\u000b\u001aPW2\u000b>PQnǣM\"oȈ 4xWaOX`*\u0012$\rt\b1Y㨈\n\u001c\u001ad,1\fL\u00015\"f_\u001a֖.3萄/\u0016\u0001`\n2!]\u00072C=R\u001daJw\nWaU\u0015ns\u0017\u0000vV\u0015͈a\u0002\u0007*.B\n@=\"R\u001a\u001bW\u0005!\u0014\u0010\u001f\u001bh#ZOpx*`\u000e\u001cnd+%\u0017\u0001r`S\u0015!yj\u001aUH$?mĀ\u0001{\u0018\u0019FYr\"~\t\\r}L]NXɕnm%\n\u0001$K\u0001,]T\u0011\u0005&ײݭ@\u0001W0T)W\f\t\u000e\u001fT!\b\n\ngUI\u001795I(~!o\u0011d;5?`\u0014>'!%sV0h\n~}ΑT6nOL}ʒT!i$tIb1\u0002\u001628zL\u0005\u0004G=je]~^GA\u0010Q'\b>=sB\u0004b≺\u001b\u001a[4D\u000ex\u001c\u0012ys~\u0012`\u000b{\u0005p\u000b\u001b,+&qL&+na1Onz؝?%\u001e\u0014\u0018\u001e\u0006ˑ2b|\u001b5&$~K;\t\u0004:G}\u001b\u0018fKBXL\u0019\u0004Q\u001bFi\u0002\u000f@\u00046D\u0015,YK@'(\u000fMW\rՏ?Nڱx`7\u0012]:\u0010l\u00155DΜ\u00138~5LA(s^AB\u0015ںb\u001a\u0007O\f\fo\u000b\u0000\u0002]@\u000fe\u0012\\> R@\u0005\u0002-I~e7\u001b~S7D%-h!P@̷?6n$u١R0+@k\u0018k#||!<8\u001b\u000e\n/\\2\u001bSynyy|\u00150\u0019\f\u0001:Ei]\u0004~KrX\u000e?vTE+\u001enR|N7Bm wi\u0014+1/L8\u000b8l\\\u0013@A\fX4]P@T-}\tWj\u001apⒾ\t\u001fw\u0004>\\7D#'\u001aᏹ%>\u00032A\n\b\u000e[ӿKކc\"$Y\rI\u00126us}1yFhg\u000fhOHا\u0011\u0003S$\u0019!\u0010\u001c\u001fY/\u0015\u000bƓ#\u0011G\u0006rjMo\rVR\u0005n`ܺ$w<#IGEF9h\u0013\u0006\"ZPvMUC\u000fgq\u000bd\u000bD{\\]8ڜ׺麶\u0013)(L\u0007m= `'m\t\u0006\u000fmN[NiN{uAo\u001fYK\n\u0019%fZM̭df;[l\u0004$7Ȉ\u001e\u0005\u0015j\b\u0016\u0000uUJ\u001fa5ELǧr(~vﶣɝC>\u001d\u0013wd>>4\br\u001bn+Rz\u0019<1$+\u0013PNft\u0014MJ<$1;@\u0016UJ,7`\u001fth\u001bId_Ri(\tZ\u0015k[O $xF\u001dOǛ\bxDk\u0002\u001b`\f;tݘ\u001e3\u0014:\u001bTX(c\u001aƕu\r\u001eII\u00018Krv拄ٸ>M|L!0VI^T\bE\u0012\u0006^魣n<bA\u001c;!*Swx\r)\u00013+4\r\u0003)g\u0016YʋV \u001fz`ԇMg\u0019V,\r\u0012pX8\u001c'x\u0004Hu\n0 W72\nT[\u001c~\u0017\fn\u0019/\u0019\u001dt\n\u0014Sü\u001e\u001d~'\f\n\u00140\tH_|忝\"Z.\u0010\u0017\"-mI\u0003\"B@F,ULV\u0017\u0018l\u001bjt[]\u0016B/bRR\"\u0010$\u0013Tوyt\f\\W<o\u0016Ŀ\\\u0011&KfL\u001aŦvB2\u001f)]N\rY.k*\f.\u0010T;SxDP\u0017V\u00042\u001b\u0012%U^RHΨ&JW\u001a\u001dҚH\u0004p~\\\u00139YRw\"O?\r\u0002BRNX@cIЯ\bḫ`A\u0002K\ns\ndʤ\u0007K\u000f=ըc\rPc\u001d6\u0013dC\\\u00071\u001413܌Dsc\nqh\u000b\u000b\u0001R4ilQe\u0004Tg2E\u000f</\u0019q\u0015Hi7/w\u0017u~x\u0010\u0010b3x\u0015x;0`\u0006\u0018\u000e&fp\u0001k+び־\\$\u0014@HCB55r:&{b^\u0016\n\u0003*%BM\rz4e\u001b Ȟl\";:\u0003nC1|U\u000eޭH\u0004ۄcqMx˽\u0019dig4F\u0013\u0004\u0016\u00166m\u0014Ak$P*\u0011]C&\u001aRb)L\u000e)R1M>G\u0013&L@Ljd\u0004\"\u0014g=yӤbߣ:&e-XȖȳФٖn(%\u0010\u0014AfD:O/@#ag4RiRnGF\u001c+1)n<๞qJN.,)'M\u0002տSUCtqI}Mΰ\u0012\u0007\u0004wTo÷$]j2rZ<2\u001aU\u0014WzM\u0015\u0019<\u0012`nlҾٱUBNApiB.\u0004J2Ӈ{ow$Z\u001aaR\n6O|5a)\u0006` `L\u001c70qaGWjjiʇjsXgp\u001brXpo-x\u0002-X\tDS#u>FGfnABhV\u0001\u0019K;<ݬQ,TX\u000eu\u001aDh\u0011n\u001dS\u0016ĝ]1|H\t<#^m5CcDEH\u0017jt~\u0018˕AU]*6\u0011ny9ry~ L\u0015S-IԬo-J\u0003/<|\u0001dq\u001e%b@\u0007u<s$қ\\G<Ś\"~!hq\u0000U \u000466M)K@\u001dƜR\u00150\u0005w[kP/⫁\b\u0007u5\u001bi[\u0018+;E`\u0001}:Xt\u0006?J}\u00109p\b\u0000a[K\u001ev\u000e\u0011\u0012T+\fRiK̡~\u00063?g\u0014. jrj\u000f_CE^\u0014\u001d6\tϢQ\u0011]\u001cF\u0002{\u0011M\u00172`T)\t\u001bwI\u0012\"/rG*.|ס`\t5,\u0010kӈ\u0004\u0005 (נiSjv\u0012v\u0012RjjF-P˯\t\f\b2Ж`C\bg\u0019܃2*\u000f\u0003(h\u0011}R\u0014ɢ\"f\u0017Q= m\\\b#T\u0004A~\n\u0000$N\t!F\u0005\u0010ce$\u000e0\u0010u\u0001;E\u0004\u001cspj?.[&&CgEԮ\u0003)\u0011uKòHHHe\u0014\u00103[4\u001fQPQKf_x\u000f@5\u001aV\u00102\u0003\u0001`\b\u001a\u0010Wja.\u0013&C̒\n\u001c%t\u000e\u00129\u001c!'\u0013i\u0003C\u0001GD\u001e\u0010SFf\"\u0013w4Cz&Ċ\u001d\n\ntlfFm}|\b1&c/[\u0012}oE!vj{FBLגɅ>\u0010Gwxt\f\u0010'Ajh3C\u0012\u0005\u000e\u000e\u0005=\t\u0000Mr\u001e\u001byM\u001dk݄.Ei\u001a\u0006\u000feO\b0֕\f=(\u001bR*\u0017\u00050\u0014!xs\b[@Z\u001ec\"HClׅDKdj\u0007PKX@)2\u0010:zPߝC/}4\nv؋\n\u00153m'\u0018\u0015A1a\u0018GT2\rv\u0012%_\f\t.藌Cd0O\u0013\u0018U\nL}MlM,W<:{`规\u0016o<S\u0006\f(xl\n5u!\u0006[7V\u0017\u0001S\u0011mBcUbN_,V˅w0y<@e\\Ǎ\u0019O\u001aȥ\u001d=2ƭ\u001c*\u001fk\u0014[>+ӗ\u0003\u000f\u0018\"#\u0013\u0003dK\u001a]Phӗ\u0014ހǮ\u0012\u0003XZJnC\u0018\u0002mY\u0002f<áMSY4Qx#q<a\u0002\u001eV \u00008fDÏ\u001bƚ3b\r-M(d\u0016X\u0006Ϭ2z\u0006+n\u00054dD\r\u0015_j(fsM9Tt\u0006aW98\f\u0001NU7\u0015\r\u0007xMg$PfX-l\u0004\u0007\b?ѭ\u001aL\tG\n\u0003\u001a\rZQk{>(m4\u001b[s\fPvǎڃ\nΟ\u000f?N!آ\u0002\fZ`t\u000eeԺ\u0003ܭQ)\u0016TYݹѶ2!\u0011_\tk \u0000]DSdFs6_-k\u0003G\u0015E\u0015X)lk58ޛ!\u001cAATL$׫\u0014.\u001cYpp\u0015e\u0017etdfљ\u0000`m\b\u0005\\Ԯ;]Pbɮ!d\u0002\f#a\u001d]ćxhkmIcFOIg@ܶG\u0017\u0001V$\u0015\"DOrڭ@І\u0013@lG&AC,4K\f/$&6\u0012\u0011caD\t\u0005\u001b,\u0005>AAy\u0006ߊG\u0013^.o0s҈q#\u001fV\u001b|\fx0l02X\tY5\u0011o9G@Bl\u0006\u000fʃǄ7f\u001b\u001b\r\"Q%c\u0011?\u001b+\b{5\u0017KϊOѽbvlp\u0004Ɩ%\u0012\u0018\u000b7\u0004b(M\f*VjXKkpFs\u001aE\u001d\u0017\u000e(Y#\\\u0016t\u001bԮ3 qrl(Z\u000eP^\u001aL܀rI/t@BB,\u001e \u0003\bD͟$f;$(ͳEOr\u0000Db\u0016Mpa(\u000eqla\u000b)uA\u001fv֛~P\u0014$'>J\u0006\u0016V%o3\u0018b\f9݇wDW\u001d\u000fO./\f%qv\r㟉ŨD\u000eԒvg1і<\u0006G3}~Z}(묲/7b>M\nv鳴,[\u000e-\u000bQ\u000e\u0017>;Z%{|]0s#\u0002\u0000/\u0001lBH\u00168T,D\u0011^ak=i\f\"\\ev8Z6jt\u0007\r\u0013^RVt@C4Sb(6S*eZq4C\u0001\u001cB\u0010睧VԧQ\u0016<\u0003\b'\u0018l}ܬ&\u0017\u0002\u0005p+\"1{\u00012\u0015\u0016rGJ!O\u0004\u0000\u00060#\u0006\u001bW<C\bp\u000ed\u0004\u0019\u0000\u0002\u001dߍCh\u0001<t\u0013\u0016zH&G\u0006!\u0002\\^˃\u0002bciH\\pS.\t\u0001\u0001\u0001U:tRJ(+g\u0019\u0005\u0006wm\u0001\u001dҮ\u0014:'Yl 7\u0002ˢn֢r1\u000e\u000b$\u000e5;p^m\u0003\u0011!k\t\b֒v{˺$\u0015T+G\u0004%\u0003\u000b\u0007oȦiӥ5\u001b^ѻ12\u0011\u00014(툖O\r\fhq\u001a\r\u0003uu`\u0010-\\S^(\r\u001b`ؑ\u001bCMbeWiMx<t-`B;\\v\\\u0001}`i64#ӅMi;\u001d^h)nv?\u0001Ĉ1҇\\\u0001\u000bZjsK\u0013f0!\u0006\u001f{5z+N\u001a\u001f=A\u0002MHo-\u0000\"rwC\u0004p%FB@!\u0018qu=#\u0011ZeN^\u001a:%t;{J9&\u0003H\rA0y\u0002X\u0017W\u0002\u0003\u0002\u001dW+\u0014GLVXC\u0010<}\t_^AQ\\S03֋y\u000b\u001a\u0016'%B\u000e\u00074EB?h53\u0015fB9/qX7\t\u000e:s)\u001e\u0011CYgRys\r\u0016VtBo\u0003\u0019$Ҋ\u0014\f*\b\u0011RZo0xnhy\u0011,Q\u0005g'\u0003T\u0005G.t=\u001a\u0004As#58\u000b\\TTG\u0007 V\\h>wJ{qj\tK\u0015~1mƁ_Udp>3^\bp\u0000\u0004\u0004upBh[⁬OND Wul2rI6<_ը\u000f9 zt׺[\\\n\u0010J.\bHD\u0016q\u0013k+޼\u0001o,&G_:\u000bKk׈N\u000e2\tbӆwp(D-SD\"xP>(r79S|y/Oɨ:\u0002\u001b&s20f\u001a,oO~T٢.'w=\\B\u001ejşΩ#w/ϐzFty<Oz\u001c_@\r!&_\u0019P­JNFzKU:Ј9\ng3^\rP\t\u0010<KZ\u00033>*A5Tͨ2w\r*g-\fD\u0018:\u001bJV$\"H\u0002V&$IL\u0013\u001f~H#R\u0015HfK5p\\&\u0010S렬B36~q\u0019bR\u000f+\u0017f\u001fGosޭl\u0012\u001aT387e\u0005{jo#w\u001eĿn\u0018\u00050M\u0014\tPu\u0018\u0006W\u001ar^\u001aX1ÿ\u001aӳ\u0006ۤ;<}Q\u001b\u0006`\u001eߘȾO \u0014'beCe\rpȪuŋ\u001b\u001a/%X!\u001c\u0000=Eu\u0010C\u0014]ߟO2俾Ga%4\t\n\u0006oC%4 \u001d^e3Kě=\u0017\u0006\u0013\u001cMע5\u0017\rM/1\u0004ujoH\u0012/~\u0012\u0018\u001c\u0005Q\fGX\u001a\b\u000b\u0007.\u0006\u0013NB\u0017$8\u0010g8 #\u0006\u001a}\u0001̉Ë\u001aL\u0003\u0007*P=\u0002ܛц=\u0011Kw|1\u000e`b&li.5<M\t\"W\u0000:,,v`Ŵf\u0007f\"*\u0019C\u001edGÎ#4{LС\u001b\"\u000b\u0006݇JJ\u0018[Pԇ\u00019\n6;\n\u001f@6 x\u0011\u0013F1xڹ&Ȳ$S|\u0004\rK./Ԕ\n&XJ^Ťk\u0002q\u0004;V;g z\u0017#(n.9TpTC~)c/51mthMXxB\\9K\u0007}P^`\u0017O)B{L\\EaX\tat\u0001\u0007\u001ebY%6G5(\u0010\u001ann7\u00015{!h\u0002L\u0019<j˙SvP\u0005\u0010\u000em\u001d+/ !f\u0002>ʶ\u0018)\u0001{/T\u0016\u0007ȎL`\u0014\u0006)\u0006֡N\u00111\u0013\u0004T@\u0006\u00070\u001b;\u0003\u000eϵ\u0013i\u001fu;]V&\u0005.1Mdݖ\u001c\u0004\u0006\u0019wy!\u0002\u0002\u0016}\\2/1E\u0003U\u001e4p(\u001d³V%\u001e_pd.Q!\u0007hQx0k'\\\u0018bSf(wh=\u0010Th8]*i0Csx8&es}\u001ḟh\u000fa)\u0013xJ\u0007S.JBCDRhsV\u001e/§\f!2\u0007@K\b(Xi;oBHKW}\u001b av\u0001|FPb2ގ=\r.h2\u00196j\nZ\u0000\u0010`C\u0019Ln\u0000\u0011XGʳ6܂V>)\u00187Q0˿\nh꘼Ê;;\u0018l'Xp@5?I\u0016\u001bqi}\u001dۢj\\t\u0019\\.9\u0015{8!J֞\u0000Γ{By\u001e\f߅\u001di8 '/o\u0019<Ryw}Z\u0000F\u0007߂nyiQXƺ\u0017\u000fb}\u0007&\u0015Zt\u001b%Y|sl\u000b&a'\fׇguW4\fӞM5*\u0018cbz\u0011✴dH͙|Y\u001ai00Σ!'f,4v\"7\u001aɮ,\u001d}K#|\u0005*D\u0013\u0010Z/fb\u000fnpA'\u001fdYn!\u000fH\u0006PG'גVC[?oXUr`4\r;G=\nnr\"F\u0012bs},Z%φ6g\u001d}1J@oT\u0016K\u0005c\"w\bn\u001c>YDwYt%Kf@%ﯞ67;ǟRM\u001bB*چmdѦ27\u0011B\nqdLmh\u00041u#\bWW\u000f݇A\u001cQQb\u0001\u0004t,ςv[\u0019\u000e\u001c evZ\u0017\u000e$/%yz#W\u001d\nA\u0019MN5MK>S$G4xP>!+L,2\u0013^\u0002 .w\t{T!\u0001\u001f纨\u0017mh\u0014M){nn\u0000\u001fIx{ #%U$\u00067,\u0011\u0007Y'\u001b\u0011\u000b*Bt9a\u001bHЮ\u0003,Cɍ\u0013N\u0010j6m\r6\u001c&0y\u0010A\u0017H8/\u001d*\u0006$rIn_\u000bG\u001ePEon8xNm\rVc\u000f,j\":XX=\u0018L̥E\\x8t|\u001bWQ`\u0001A/_!.6m_\u000fL\u0000\r&V\\J3We:N\u0004\u0006[r\u000f`L\u0015p\u0007c{gm/vS\u0012'\f\u0004\u0013XsuZuKDQ\b\u0002ߘ\u0005) \b\u0017\u0018'_aw}\u0015.\u0004)\u0007),.oհ\u0019-\u000e\\c(7Դq\f\u001blx׳Ј)]p\u00073a`MChXDwvKa\u0000){P\u0015\u0012\\f}:.㫔;'Id\u000be\u0018ƣ~\u0013`\nJ\f\b?$i5 D6m\u0019:rQTDvΫT\u0005C4Y8\u0012<ia|c`\\\u000e\u0006e|bP;\u001c\u0012&\\gA\u001fTP\u000ef#~0rQ9\u0016m \u001caW/ڔ34\u0002\u001fiV\u0006Յ|^\u001aߟb\n\u0003Az)\u001f\u00176[\u0006\u0018\u0002s&\u0011r)n\u001f\u0014-\u0006qaD|̛7.,SJ\u0003oܙ\u001e\u00019u\u0011cn%\u0010B)?Bio&Udz}E\u0010\u0014Xc84\u0012D\u0000E5\"R<Sc-\u0013xkO\u0014a\u0003C\t\u0006v\b/k4d\"~bZ\u001fq+7ڋ$\fOkR\u000e\t'M\u001a\u0007\u0017jO4SnK̲Q\u0012aOB5;z$H#wm\\RX5\u001fAv\u0016 5RÍMnc\u0002V\u0003ǩ\u000fa\u001bZ\u000b'gL'>Ok(;כb\fհm9~@J8x\u0005P\u0004Vc!Y$\u0004|y{@\\V\u00046\n(5\u0003L=gbWEh\u0015𬉰` }*\n\nM'4.uU?\u0014K?P>\b\u0017\tT!>Lֆdj,\u000f\u001ajٿ\u0014\u0010?NR\u000fz䰈YZVh?!-|\u0007\u0018t\u0005}pDZg@U\u000f\u001d\u0003kEt\u000bAV\u0004*\u0004#!Θ\u0011<T\u0010`\u000f\u0006ܛ\u0003\u001bL{Msg/:U͠D s>!igJ\r\u0015Pr\fq\u0007bG]\u000bfs|Nt\\\u0010V\nfxI<6:\u0005*_6=g̦C<^My-Ihr#̀\u0011>K]8\u0014\u0000D\u0018\u001446<Jo\u001f\u000bM\u0015ĘU=\u0018t*G\u0016c@\u0014\"\u0017~pG4\u0010m\u0004Ǵ\u0010Dd(&l`#\u0015ƨwSo\"\u0015\u0003UkѪ:.y8lR>\u0006\u0001v/aTDp㍍%{<z.u\nڎ\u001e0d\u000e-fy(6\nc\u0005;?GTpk^t\u001bYbؘ\u0005ڌm0JOm\r'\u0001R9>ZW3Hvߦ%\"򩏢\u001a#ht#\"Yv\u0010\u001f\u0012V6\\ 2SvـeZ\u0007o\u0005XӨS}oTġ\u0019K`\tu\\(-\u00195\u0016\r\u0007K\"!}| ma\u001d_sV\u001f3&er{&>9\\0\u0012\u000f\u0016(_sLÞ qU\u001bZHoK\u0002+/{׿& -Z2\u0011,\u0013nJ5Jpq\u0012.:/]ߋ\u001b'͇<ާV\u000e\u0010\u000e:s\u000e: g\u0019*pܠjp\u0001\u000eZEK%eF)߁\u001bsXK=\r\u00009\u0005z\u001ey(A$6\u0014f9\u0012(|j;N\u0015Ε0P\r\u0018sF\u001cOQ\u0014\u001a\u0015\bNӨ8~:rM?4R50,\t_W\u0012'@3<\u001c,\u0018iL!\n\"RS?J3\u0017W^1QꚐ\u0006O\u0013n\u001cM܋E5\u0001<?Zv\u0004R\tim%\u000b)z\u0015 \u001f@q\u0002v\u0003\\\t(v\u001bԼ\t~?9pbFe-7:&\u0010\u001fY?hKFLG\u001bs'MNgrS!\u001d;=\u000b(ܰ#\u0019\u0012m:Ф\u001f,\u0001\u001a0{\u0006O\u00137|~33UJ\u001bfmj\u0000:>\u000eN\u001d#,\\ȩ:c{\u0017\u001dzf\u0007ކ[\f\u0013(N*\u000b*\u0004\bT\u001b's^^|T\u0018z\u0015\n6F<1,\u0010\u000e \u0005hʵ\u000eQ\u0017;\\d\u001bؘn\u001b\\$\u0010:\u0007l\u0002~򾉮v1<<x\u001d\u0006X _l@ ⶳna\u0018qIA\u00180E6\u0000\u0016Ⱬ\u00030iV٦_:=\u0005k-@\u001aX$~>r\u000bZJn};+-\u0015F\u001c)=y#\u000e4\u001a\u0006\u0016\u001b\u000b?R_ȸ*\u0016\u001fT\u0010Q3rr\u0012Zn\u001a\u0017:\u0016'%0I0\u0007\u0003Yg\u0014DY\u001d\u0019Jn\f\trmUBD盝(2\u001ek\u0019m@j'(\t(\u001bY\u001cfUlc\f\u0000o\u0002t2L\r'dGO\u0004_+@dXĦ\rߨsAflԂFydn|5o0r\n>fuRU>2!FsMEJ\r-,\u001a9v}(f\f\u00061e\u001e&$!\fǐ׮\u001fѐciE(\u0001C\u0010Wo\\rWX\u001278\u0014Ȳ25̶¦/غGBCBS\u0012\bH\u001bN\u0007\u0015I0y\u0005@\u001aM\u0019hd\u0007\u000f\u0018ن?N;2@;Ɂ\u000fZ*%\u001bS+(0\u001b'>}i>I+|%{:xZ2As\u0005v\u001a*AY.|\u001d\u0002\u0002Yd\fn!\"b5t1fHҊ\\vO,#~??-N*1\u0015x\t\u001bN9\u001b\u0011y\u0012\u0013¦pw\u0000\u001eq\u0012ڵ! 9k#Ʈ\u0005ᑴXc;\u001a-1\u0001\u0010j3x08o\bL2v\u001b72\u0012\u0011>qꅥwV\b\u0018آ]M\u0011\nZGb:\"ӝhs@\r\u001c\u000bQ\u0019&r:LĝDRYI\u0016Ѩ\\Zr'I[\u0014[\tQ\u0007 uB\u000bL\u0011\u001b|Hp\u001e^{\u0003j\u000fd6\u0017E\u001aTaznЮ\u0017( g\u001cUs\u001d{sT _~u_\u0016vt\u00158ݐ\f\u001a`yiIuq?\u001b\u00163Q!oK\u000fb\u00036'cfi/yS@k\b{\u001e\u0015٩9\fx8u\u0010 QF4\u0011Ò$@9\u0010\u0011\u000e\f\u0004΋0HŨs\u0002o([\\)%\u0007Vzf$6(k!,j~\u0000N,0Կ\u000f\u0013\u001d-ژ]\u0007qM\u0010\u0002U\u0016\fuF(\u000e-e\u001fȎ\u001dؖGOsj\u000fk\u0019U\u0000E\u0001ële_|y\u00140;#,C[`.:@I5C+\u001c7k\u000e\u0005ʒsfѨE\u0011h\u0004[L\u001bLrL}O\bh\"2\rP2\u0011{\u0005J k\u001bx\n;\u0017uNi]I[r\fh\bz\u0010b$Ԟ\u001f\u0013.\u00039\u00135\u0005V\"\u001f\np[\nƌ׆\u0011\\[I\t}^\u0016bJ^\u00043\u0012>ACݛ\u0001bѢvo;Z\u0007<=1\b9\u0018*s7g,\\\u001f\u00116I2\r6|Lx\u000fR32R)^\nrn\u0017\u000fDV\u0018^_5\u0003\u0013{\u0006(1\tjIj%`;e\u0014C\u000b9Q%E37jO_f8wNC{\u0017Kё.Őz\u000eIT?> 8Fܹ\u001dB_\u0012\u0018\\:hޤ\\>LVt>8n*UVVk\u0014\"Er6\r)\u0005.pgueܾd\u001bT\u001c]F,Bh~x5\u001aXVɸFK@P<6+kōc\u001bPSz©?L4\nǂ\tNP:\u0012dӀ(@WՖ/{\u0007P~Qi{\u0001Fu\\\u001aEH;g(\u001a\u0001csT@r!\u001aJǔS-?@\u0011(W\u001b+}!FH\u0002:\u0007\u0007z5I3$Uٛ}1\u001c\\c/,@k~\u0002*o\u001cɢő\rC\nyAB\"\u000f\u0003G!*MA_,\u0012[VY*|A\u001divI;U\u0010uxK\u0007w cԛ\u0000\u0015\n,݀>{Q)BvЯ\"t9D\bra#dOqP7jr\u000b7M\u0018Rkp Km{p3J\u0000\rK\u0011X(CZ`tC/>\u001asZ-i[\b\bW\u0012#g\"@ja\u001f\u0007ً\tʺTl>\u0012(n\b'1ڱ\u0016.Ȍ?Qp&m\u0017\u0019\u00102\u0018L\u001cta\u001e\u0003''\u0004\u0003\u000fw82\tXč^1!I!\u000e\u0010HTT.js52tflEq~\u0002o\f&\n-V8\u00015j0$KY8.$\u000eTY7T5T\u001a\u0003I8$\u0010c?\u0003=(\u0007p|\u001fyJ%.x\u0007dk!Ő\u000f`eAӤR\u000e\u001d2M\u001aC #D}cH\b[VLN~OmՎNA\u0004\u0012z88z\u0011x\u0017\u001e挽\"G+}L\u000b\u001c\u0018.~Io)|Ș\u0000p\u0007\u0003\t\u00031V\u0000T\"OZtsZ\u0002\u0003?\u0014\u0003^\u0002\bD\u000f`Rl-=\n\u0001\u001e,tP$2b\u0005(hx\u0000\u00057ӊ\t\"1lӃe:2L+Ǆe?724\u0000\u00039,;z\u0018[\noF37Y#\u001eεmS\u0018c\u00111F\u0017ޅ\b\rd[3;SX\u0014Y\u000bEx4^yOFC\t\u0018/O#\u0014<;l\u00163ALX`\u001c԰8~MpDU s9ˇ\u0012\u0003,\\/D`H)ARsTv8MN<!@f6\u0018\u001cD\u001dCO|m1DAb9\u0003\u0001\u001cΐ\u0019j\u000e$ȷJ\u0017PCp\bLD(I9C\rM`%N\u0003\u001do\u000f/\u0013\u001f`,|\u0002t,4-nXw(3┶\u0013\u001a;\u0001~JO'=k\u0002m\u0019嫙6\u0012jJ\u0018tִ\\uLjO\u0005e\u001c\u001eali+N$3;*Y\u001870/Y\u001fr?\u0001\bj-LK\rfuB\u0002|~Tޭ͵\u0019GM+{w\u001cA\u0001^0\\xP\u0001\b\u0005\u0005}հB$%^lcg#.\n\u0013ƜC3\u001a_ꁉkXV\u001a\u0017MȔh6I֠$A\u001c)ӹdU\\rU\r=(Y\u0003m\nʌ>r&\"+$\u001a=\rmb۵$bԙtγ=h25jh\u000ba>&ցI6iz\r\u001c&bƃυ\b\u001eǑh\u000e;erE12ǣ֥\\W2,uNc\"8U]C!9UEvx1Jp`\u0019cqEXT\u0007Q(\u000e_\\n:,$\u001aW\u0016mX]^k\u00121I#\u0012!=bm)Yźú|&u5('}_kv&\u0013^\r\u0013MBq\u001ff\\\\FRqbs$\u001aDU\u000fe6E\u0012\u0017hBOg26sA\u0018vR9\u0004#sLl\u0014\u0015\u0016Z$\u001d̍m\u000e[D&WFFmX.;5]u9T<\nqSxK+׭6tb\u001e\u001ctL7\u0019\nAK#}d\u0003^s'NQa1|ӌy٣\u000f\u001dQΞ\u001f2+(\u000bujwۉ%EGwp>=I\u0017rȇ\u001c]~JJ2N\u0014RTX2z^xtٌUHf'\u000e3:\tI\u001dN-k/'JJQaFP\u0010tY6ꨓ0{i79vЯT\u000f/u\u001d#ʳsY/=ל\u0010v^f\u001e:\"թL\u000e*\u0016]JQabP\u00163<hR\u001a먡:\"\u0011R宣\u0011F5biQ,e\u001d屚!%uhat?,QfF\u001a#\u001c\u00195oЌ%Ɍ8;iGX1\u001aZ|fut\f)~\u0004\u0014\u00150\u0018\u0018(*P\u0007c(*F\u0018!\u0003Eŉ\u0017F0cCG\u0018 \u0004\u0003(q\u0011\u0014\u0018pС1cn̸qH\t\u000e`\f!&\u0002\n<XP\u0006 `C\u0000H`\u0005\r\u000ex.N\u0018\u0002\t\u0016\u0019(*.h\u000e\u0003\u0004!J\u0010\u0017`p\b\b@\u0000\u0016(\u000e :\u0013\u001f\u0006\u0016)L\b\u0000\u0010\u00005\u0001\u0005\u00060\rh0\rP\u0018\u000f\u0010(\u0005\u00038\u0001@8 \f'\u0018Ȱ\u0002\u0003\u0001\u0010\u001c.\u000ba\u001fD\u000e`Ȑ\u0004\r\u0005\u0010\\* \u0002(\u0018@?$\u0003\u0019(*,D\u0004e`*`\u0002\u0011\n\u001eJB\u0012Ja<\n&\f\u0018B \u000b\n\u0004\t\u0001\u0014(\u001d6L\u0000\nځ\u0003\u0013J\u000e\u0017&|\u0018\u0012\u000fLlt\u000eFp\u0001.\u0004\u00010Pb\u0005\b\bJxJ |\u0000\u0001\u0001\u00028\f`,\u001cA\u0004\u00065\u0001\u0010h8\u0001\u0004\r\\h\u0010\u0001ha8XhF8ɀ\b\u001e* !\u0002\u0007\u0011$6 a\"\u0004\u0011!Bp\u0000D\b\u001a,E\u0007\u0007X\u0001\u0005\r\u0016X\u0000\u000f#\u001c\u0002 h\u0014\u0002%T8aгf\u0010\b<\u000bP\u0017L(\u0007\u000e*\f\"\u0007J\t\u001fB@\u001cD`A/lT\u000f\"\u0016@@@T \u000e\"\u0012$\u001cPDY`\u0003\u0004$ \u0001z!\u0001\u000e\u0004\u0012X@B\u0001\u0018:\u0005<\u0003\u0004*t\bo\u0003\u0012P\u0019(*0x\u0006tp!E:p\"78`:T\u0002\u001a\u0011!B\n\u001f@Ha.:h\u0000C\u0006\u0007\u001c\u0002\b8|\u0012Y\u0000A\rB7H9hA\u0000\u000f\u0000\u0002\f\u000e\u0010Aqp@\u0006+|x\u0001\u0001\u00108@\b\u0010\u001dV@A\u0010+|Ѐ\u0000\b$(\u000f*\u0007\tL, A\u0006\u0000\u0004\u0005\u000b/p4\u0001\u0006\r'\u0000pM0\u0001\u0013\u0005\u0004ɀD\u0006\u000f\"\u0016\u0018\\\b\u000eg*(\u0006\u0017C\u0006*l]C\t\u0012\u001b@\u0003DP'\f\u000b&\u0010\u0002i`\u0011\"\u0004\u000e\u0017\\\b\u000e\u001c>,\u000e`@\u0001\"DH!\u0001 J\u0000p\u000e!8`\u0017)\u0006\u0013 X\u0007\u0011\u0007\u0001\r R\u00183\u000b\u0010p\u001bn\u00030/\u0002>\u0004\u0004\u000bF\u0005$Bp\u000e\f0\u00108\u0000\u0007\u0002(PB7PA\u0006\b\\x.\u0006S\u0000\u00120\u00015\u0010\u0000\u000f4b\u0000&x0\u0007\r\u0001@\u000b'\u0002\u0006\u000e1\u0014`\u0004\u0006\u0005\u0011\u0019(*6\u0000A\u0001\rF\u0005!P\u0007\f.X\u0000\f!\u0003\u0017\u0004y \t\u00144\u000e8\u0018aB\u0006LPA\b\u001dXd0\u0003T\b%L@%@\u0000\f \u0006C\b\u0003!C1\u0005\u0000< \u0004c\t\u0002 \u0001\u000f6A\f#E\u0003F\u0007\t!8\b\b\u0017\u0000aBp8\u0015h\u00126P B\u0002b\u0012\r.\u0003\u0013\u0013\u0000@<\u0010\u001c\u0004\u0002\u000b& \u000f.\u0004\u000b'İH\u0004\u0000\u0000 lpB\b8\u0002\u0003+\u0011/\b\u0004\u0007`\bN\u0007\u0017Ç\u000e.\u0004\u0007\u00007\u0010\n\u0010\t\u0000D\u0006\u0016\u000b\u0013h,lB6\u0010\u000bxBpP\u0017L\u0001]؂\u000e\u0006\u0018\f\b\u0017D\u0004\u0012%(pAbR@\u00059%:B\b\u0011\u001a@\u0001\u0010\u0001\u0011@\u0000\u001aP\u0007\ba:`\b䁅\u000f\u001cB\u0006\u001f\u0001\u0010\"P\u0001h\u0002\u000e\b\"\u0003\u0006\u001dHA\u0007\u0013,9L\u000f\"\u000e\u0000\u0001\t<\u0001\fh\u0000\u0001 'L@\u001a\u0002f\u000e\na\u000e\u000bl \u0002\u0006\u0014`D\u000b\u0006\bA\u0003\u0011#J\u0010A\u00031P#\u0010\u0001\u0002\u001f \u0000\u00100\u0012\n\u0004\u0006I\u0000\u000f\u0000p@\u0005k\u0000\u0001@D\u0006\u0000L\u0000BD\u0015\u001c0\u0002^\u0002\t\f>0M\u0002\u0004\u0003F\u0000\u000f\u001b(\r\u001e6\u0010\u0006\u0002A4X`\u000e@\u0000\u000b\u0005<(\u0003T\u0000!^0\u0015PЀ\u0006\"\b\u0001\t\f>H\t\u0014*`\u0011\u0011\u0004_\u0018ku2qT*\u000b[s)kem27^(*L\f\u0015hŒ̇MR,u\u001bTivg,̕(*,茕R47\u00124|Io$u\u0003v^\\\";[]g\u0013a!;\u0013W\r\b~򏣴`\rJ[\u0016kn\u0012\u000f+azOcդǹ\u001cRTXԔf2ro\u0006\tY}^AS\u001bʛ\u0014\u000eU\u000b\n|(Þw|?\u001dk\u0006g*oX\u001dXqV3.6KýbGQтNX$/v%3\u001e۩ly2Y\u0019Ӗp\u0002\u001f(h&rNU=ɤ0QxC\u0007S0+\u0011\u000bo<;qRT\\PG\r\u000e\u001aN^)\u0015֙\u0014\u0019JMIlwx\u00164)4\u0007f\u0015)Sǲ\u001a|1)Ϥ9^2\u0007}rĚK\u000bMQMSU\u0013Ε~+߷\u0019K\"J-M\nQYسG[\u0019Z/\t_gzS3s'FdtKgfM\u0016Mvx{wtRU3/cNh>I<4[򼰰lo\\#:o>x\u000bZs$bsŌrFja^hXUE5Ct3<iHwv4æU<7Ȫ\u0017cF)x\u0016FyI5G₢\u0014\u0015\u00174vώl)*,D\u001c9T:ڈV\u001dSTX\u0018\u0019I;\"!D\u001fj\u0012Ъ:RXwb#kl?>\"9:mJJmUv\u000e\tJff#ju+Z\"GhE(َSVt|MS\u000eS/(*,dLQqaJdRSTX:\u001e1\u001eR<,7#E8{h~)\u00134EŽ\u001dg\u0013\u001bB3q\u000etL\u001c-Df)Y\u001b,ՍT{QfI[1\"cմdNQ\u0007JY\\]X(me<(JQ_I8#C180\u001d\u0001\f\u0002Ejk\\sudj\u001b32V:\u001c5)\\&w%\u0017=79id̘u\u0015+bhvZUy\u001cKP;\u0012Z\u000b}Mh׬;YH(3\u001d>NYҖ|;de;&b5Ksh.%aX\u001c\u001f%AI\u0011f!߁3WG1{\\>)7Y\u000eBǪ]\u001d1\u001cyu]xإjF#knhl~.qHxi^K/B|dY3vT.i\u001dVH7IS\u0005o Q\u000e\t\u0007+B7\bq9wBf7[\n\u0005m<\u000fu\u001dH\\YBĢ\u0014̇~\"tɎjNʒ:N#hmm\tu!e˽RM=e:*_#dm_U犒#_$di͹\\i\u0007UQ\u0007\u0011l,Fw$X95%;ʮzYp5TG%H#KEQU\u001fojZ \u0015Ik\u001c\u000fMi#\u0014\u0015\u0016j^Zd}\u0016ˁ67]k\u0014Odd=H\u0006]ӞY|\n\u000bRIi\\uB7e\u0019uz[\n<9GQa\u0002S~O<i)g\buuFQabXNϵr5JwW#,[d8\u001d\u001f#DÓutO^gB<\u001bAn^|ec\u0001ϣ9^ӓ?\u001aPQYGe~^NJ1\u001cU,4t\u0019\u001ciV>jyl5dAVt#&r\u001eAcFtx,\u001c&\u001aƮ=_](\u0007r\tԝGRo\u001ft&?ф>/,֓rq`5}\u001e{ܲس\u0014[\u001a\u0019\u001cT7ՓC\u001f\u000eM\u000b{ \u0019ZV\u0003sp:w*̈\u0017_I:;L(eN퐪SSuZ\"&܃Ҩ3?Es6-_X\u0017,&\rЍQξ3Rkմq\u0010ٚb\u0016%\u0012g\u0019K\bݪ\u001cl:\u0017͝Qk\u0015\rږdNvA\u000fe2.\b=̉M=GT+\u001bm˰tIɡ>-_fkbM\u0013\u0012D4N\r4f '6LJ_\u001e}Wˢ;;E\u0005=#\u0014\u0006aoV{:hb94.LG2hKkaߕR)Qp:\u001a~Ds\\;\n-qΓb1tM\"9\u001bΌMG2A=(g?LM]ƒy\\D,?;zg\u0012;XcUILulȂ6wb\u001aEEF:~cCK\\#9yr_f:\u001fA\u001cv\u0011X}'\u0013ZUݔ?D$c\"4\u0015\u0016ޜ\r:䫒\u0019{nVfIYӮ͚,\u0005d7#56W$\u001fhP^OgrR\u001d=&}\u0010$a݂wq7r%f]Ӳ?Ƀ~7Wn*a%bQ?5zɮ#2㵔\u0015YȞ+g\rv^8fy3vY\u0005d5pf\u001aIiƆcrYoKʕ/-W\u001dKޢtDo%\u0013[\u0007%\u0019b\fTfͤkE\u001e{h%:\u001bURX3YN:;rGɟ\u0006{Pk8tt9<ttZtow.\u001feryFM,I?5]M\bǑᑼ(*.g9wDɲYR\u001c4W7o\u001a9yGQTsaH\u0013qDT)l]Ͻe5$h$s\u001cIR#;2*QeҦY\u0017wieh?ʛZpJJ%fy\u0011nt)f\n\u0013e:|\u0019Uo<#F\u001dhK\u001c4Z83R6hz8bqfZ7\u0019<L\u001c:jxVb?\f] \u000e\\U\u0006\nQ(\r\f\u001e\u001dCJk_b\u000bU\u001a{*\\`Ю\\#0<$bB\u00194+\tb7x>r8FX=+}YSɜ+\u001a~~XD5\u0004K\u000bɜ{\r.;ڹJ*\u001c0OYR毸\u001d1A\u000b+$NRoL\tQ\t4߱S^V|͘->ߔdEo\u0018\"\u0014$8+hUn{{G?uVRgY4\rL`\u0012\r_ǵ\u000eR-\u001d\u0011~P</Kx-ȞU<hg3B5h|(1:\u001bxV6t/j.A<\u0013;\u001eɸ\u000eKʚv\u001eT?[\b\u0014\u0015\u0015d@A\f\u00192PTB\t.H\u0001\u000ba\u0003N\u000b*\f\u0014T(\u0005\u0014N0P@\t0@Q\u0002\n\rX\u0017:A\n鎄v篹l\u0016f.Ùq\u001cQM]I]s:C7̺2¡s̬8'qGcJl|36'kɢ~\u000b;\u001d!<ihDԗX/\u0013i#dVP!\u0015Y\u0019̸7$4ϳo,\u000336%#ol>\to\u000e3\fyFCy8sgnEX\u000bg~[\u0006MoJ\u001dqt8a>\u0005w=̚\u0011啲7fcwd\u000fs\f[wsx6%\u0015\"U߹CHU1\u0007.k=u\u0010\u0013QpФ\u001fE.(7'=MXͩ\u0012/g0gf<W$+\"#)ɬ\u001b^ڴ+4\r]}\u001a_ɣ7&*\\1LrUr\u0015ڇ\bfgc\u0011Ӕ²N<m<R\u001fDTTu8G-MTRC!\u0012~\tM^`\u0015ևeb[zuJV!qaN\u0012tg\u001dJ*c9'+_:D4LA\u000f}E\u001c;OuY8\r%=z{A2B)\u000e+̚^}=SחV\u0013=3Y8|*1\u001cY\b3\"OXg\u001f9TVՒ\u001f\u001cIʍC;7s\u0010R%*^\r\u0019վyF=4\rKz١i<~Ż6\u0014Mc?WrD2,;12+sf^\u000fL,\u0012/'\u0014\rezwr9jCǢcU\u001dnx\u0019Z;ه$&u\fe,\u0014[rzuY[8j#ڙcCTfc+t)Q\bW\u0016~T\u001f\f+\u001dg߄pTfher\u0016>xr,/CG\u001eK\u0015\u000eHʩnaz|t\rpPmT*<>z6M;ļhixe=UW\u001cZ\b\u0007WX&.ݙm\u0018bS\n(Ghr,XߩG7x!fY\r\u0019ZU\nӒ+A䏌A;?Μs*L\u000f=m5EY\u0004il7EϽ\u001d\u0007jnj9q\u00161g\u001b+O\t(m\\Ԭ34s\u001f\u0013\tMjXfTϟG)e=4ù)܎Vʣs%H\u000eN*|ٝ\u0015݇\u0012GwvótU\tN3_K6$t\u0014dɒ4#n'!O*˓mSs]fc1\u0013;YYO8whwއM3n8_\u0007Yչ2YIHUv%VEm6)՜ѯGIOK$9WO\u001bK4\u0013\r\u0012+Ҳ̜y*:\u001b\u001c\t~\u0018QEvNpPo;csMeY(K1R8\u001bk;C31\u001c)t.^EVh>%N%Zdc\r\"^T{Yr\u001fe4묪dҷ4[i;4D\tNϓ9͢(/6L3\u001eŞƴ\u000f?iy$-\u0013,\u001cBS\u001fTc\u0001\u0013KFy@$\tE!r \bm\u00033\u0011\u0000\u0000\u00180\u0014GEQ\u001a\u0001\u0014\u0000\u0004ȖHB\u001b\bCA㐚B\u0010@\b\u0000Ȁ\u0011\u0018\u0010\u0007Q\u0005§?<\u0014\u0000r\u00079nEʟꆼθaZnx\u001c8Qr\u0000闖QF$BGZUȝ8&@Cˤ\u0013Hi$\fA}-j8֨ɸt(\u0010U{DF|\u001f\u001706_\u001aӬv2RnS'70\u0017\u0003ʿOy\u0016<U\u001f\u0005XaȤc,U}f-OGYt@G*OÃ\fz7$\u0016\u00038-c3\u001ds|\u0007wh\u0004\f:Pv:j+ܡ}9\nUHΐh\u0014~7A( #e\u000fh\u001a\\c#aEμV\u0006}\u001e\u001e=h\u0010\u0006J\\Fx㖶<w$z\u0019S\n<d󌚵~6I,I{(\"F\u0005\u0004I+@VQ\u001eϋ\u0005!O\u0006ah\u001dc&\"K\u0017-\u0006ؐ\u00025\u0001!j۵U\f*[\u0004:ꚣ\"\u0006wT}b,@\u001aAˡc%\u0013 8ixx$,\u0018x*\u0012z\r9\u001f7xd\tp\u0000 eMM:<qa\u0002%/OE#<NX\u001dmD<ZOG\u0007\u0014\u0006\u0010KHO::]P\u0016c,R\u001c\u0011b.$`'`\nD\t<i\u0001\"$fN\u0016\u0015\u0016T\u001bh\u0005\u000e9#\u000391Ѿ\u001a\u0013aon\u0005\u001fL'\u0003(lqV\\\u0007xQ1D\u0017{<{~Ne\t\u000b\f\\\u001e:E4!p$Ԑ,A9\u0011<jkm[إ\u00044`Gy,^`B|2ĠCp6o]v2y#>WjrR+LlCRˣ\u0012ȽBDV\u0000t}+[O:צ\u000b^mK!5\tNKa\u0012JӜz\u0007=Zg\u000fz#u!^m\u001aQd\u0007u\u001b\"\u0012\u0019A]\u0012\u000fb\u0005T\fZ\u0011gvuͷl/DB%\n\u0016Fv\b\u0003S\u0017\u001dD3\u0018n8y2\u0015&!/\u000f\u0011\b%%\u0010\u0015n\u001eh-\u0018|˓jȱn\u0015m\u001aހ(MG!Qa=>\u0016J\u000f\"6&H;9EkA)aPW8E;`\u0011\u001b[f]hQEEx\u0006aQ\u0013=!KAtR\u00146\u0011}M\u0011a\u0015|\u0018IpCZ\tމ0ˉZGY;asU+\u001e|0.\f\b.#?\u0000d\u0014@KNuçS\u001b]mŐEKq8)Mޡj\t$܉\b~\u0013(R\u0001gb;id\u0004&z\u0011b^*\u001ft,G\u001cUzDNKy6\u00033\b>2*|24A!I+\u0002[?á]ƌnVQ/\"\u00038n-\u0001ʖJftJrzUB3\u0007BA+\u0010\u0004$u29F\u0007r(\u0010\f~\u000e\u001aFǋ\u0015\u001cu5\u0017yw#5\u0004\n\u0014Z* r0JW-V\u0014\u0017\u0015x|ޢ5iuqq\u0011%bDMOT.kJ:;!\u0018.R+\u001d1\u0015X.~qF9t(\nc\u0010Ӈ`=ZD]\r\u000b\u0019&&L.gӓ\u00113&˝D!<iЖ\u0015E\b\u0018,#\u0012U}цkV\fq-Ad\u0019ͩ!e\u0003Ne\u0000\u0007wN +Q\u000fe%\rʫ\u0013i[\u0000F_aXm]i#*l\u001e|]j_BghCs\u0006\u000e]-:;\u000fțV\u0019z/\u0014\u0000r\\tڟ 3w\u0010a\u0014)\u000fC{=2ԲJ+\u0010\fb}\"Aq\u000fEh\u0004e\u0016eC\u0018:˴w\u0007@%\u0011Xpo\u0011\u0017\b~4P=\u001cZ~\u001e\rd?\bh\u0003B>{rGs<L\u001e>Z+hʞm\u00078f\nuH77zMW\u0011\u0005h\u0010e\u0004^\u0010oY\u0012VUzcu$%Oꔃо5.ϧԀY\\`\u0003\u0015;yf\u000eʏc\u000e%8\u0002yck\u0010*wvH\n$S;>yOĹaFd\u001b(AF/9\t\u001eqg(x&x\t{jiFx'۶h\u000fF}\"k#_tR\u001bb{:\u001bQsDdħ=/17\u0002}>)Z\u0010\tp\\CE,[\u0011\n\u0016'Kʠn{٨2\u0000c4*t\u001b<\u0017U݅9Yw\u0018_dٛ5\u001bafeO\u0017Q\u0002W=X\f&\nCgܗ\u0012T?\u0007\u001e76rKt\"2*=u4h\u001d\u001cPgifM[Te-]u:\u000b\u000f zn|Oɚ8:ێf\n8Yp-,\u000b\u0004 iuiZъT!S5Q;\u0016rK\u0016瘴Z+zH Ih\rV0P|\u0004uJA,zW,\u0017lp\u0006\u0019\u000fC9R\u0000@tҩ\u001e\"\ts\u001fU\\2\u00159]5\u0005|Mة\\xЈR[^\u0014t<N2&qsnٶ9G\u0017\u001fkͳ\u0007F98$\u000e2IBi\r?2\u0010\r#\u0001lb\"F\u00014ž8e\u00171}gau2mhJaћ <\f`rg\u001cdWS:eă1S)+\u0013\u0001\u0001d\"\u0017y\t\n\u0014\u001ewÆ!VȌ\u0003H\f斓\u0007ƪe\"\u000fZT\u001f5\u0011(Lm\u0015IT\\ۺY\u0004\u0005{Q\u0000lB㳢z\u0016\"اpDH\u0000:jK9\\ȄEhK@\u0019/hEҫA_\nxbj`:`\u0011\u001c\f0\u0018]I\\Z\u0007˞\fY\u000e\u0002K:?U\u0013햿Z3\u0017?ߖ`esfks(Vg,\"\u00107,=@p\u0013-\u0014 UPfG\b\u0012lreg\u0003-BsLS\u00184D\u0017L=\u0012\u0011X \u00151{45\u001cbUϕ#\u0019ǎVҙc\u001b\u001cd\u001d\u00040xSBT\u0016J\"0Ј\u0016E+\u0011[\u001aS\u0005i@閯#R\u00062\u001a\u0016I\u0015~h&\u0016Q]TC+\\\u0011_\u001c\u001b%Th\u001c+j΢TdءO~+=\u0005O\u0019$S\u0003]#;X\u0004G/ \"ouPo7XÖX2|(\u0019gf\u0005\u001aJgzװ\u0010\u0006Li\u0016%NH-_ȇ\u001a\u0005\u001fqK\bL\u0010\u0018\u0007(\u0001\u00136m+iΖe\u0013M\u000fH\u0016\b\u0019\n)g{>\u0002VUBP;\u0014`*h6pXB^?Zx~\u001c,gz\"Z+KI\u0006_zX\r~dD~,t\u0001\u001a\u0019\u000f5?\\\u0007w\fKFDg ?u-+7Ы\"(\u001cA)aN?k(pԝR\u0015\u0014R\u001dwE^;]\u001bFUp}ߠ\u0001eT2k\u0006E#@9\u0019bxN\u0016[Eo4;,,dqDa=\u001d,ns{X\u000eBhJ\rs=I$sA\u0001ϝV\f\u0010/;]Cn؝~'7<(\u00127\u0004ta\u000eSi[\u0018Q\u0000||+Ui[a( Ο\u0014w0\u001e:Q\u0005U&\u000bOrC\u0018X5_4ڃ\u0006.ac7x~\u000fn*:=UĎΝƪ)Z8\u0002b$ƙ\u000b{r_\u0005\u0011?G\u0004zE\u0018\nwп1_}`\u0013~DVPc4\u0017}E7u\\u\u0007\u001d\u001djh9zXݮ_-ófp#@U\u0002\rD\u001ct\u000b<\u0002J(\u001b|].j(Cf\u0010W/.\bK\u0013(T\u001d\u0016\u0015e4P\u000b \r\u0011\u0011\u00189_\u0005?\f\u00105ާϚM\u0001+*4\u001700]5w\r\u0000`K-K$3r\u0013UX8\u0010\u0000S\u0005\u001cp8\u0006}aYH9煄k|)u}ohqo+\u001cbF\u0006MUl62\u001b]%@vmfB3diQ y\"ؤ\u000eCO \u001bng\f\u000eX\u000f*ee(O\u001c\u0000~5x\u0019)@Yٚάn&aH\u0005-:Owv*w7N6|\u0001|PSNW\u00006\u0002P'8[\"?P]|7\u0005]{ǧYrJJ\u001aؗl7dZ\u001dަGjy0\u0001W\u0004-u\u000e\\\u00056!ZA84+6W\u0018.\u0017\u0002zpO\u0016\u0000\u0019x\u0006\u0007\u0015gAD%\u0004%)dvlj\u001bpkWCrUD#DX(.^\u001cPȬ_.><>{FC8^_#\u0006mC\t \u0005ą\u0018 \ncS\u0011g=E]m@Vm\u001fΕN\u001bfL\u0016Jn\r.x\"cw~d\u0006S\u001dUHA\u001e\tof4\r\u0011;++y\u001b}8\u001e5$ɮEefK!B\u0002\u001b\u0011\u0006pz\u0014˰\u0018\u001cP6ps\u0010㈏\u0003諵18Ɇ\u001fIuA\t\u0001C\r\u00048)Ģ\\\\Vҭ\u0007\u0012jNizR~h\u0012\u001cCMޮD&d\u0016P*\u0004\u0005;z\u0007\u0016\u001e;7<W#c\u0014&\u001ct$N\u00035\t\"M\u001do^ҼLg3\"MV!pyKp\rѷU3@c}g)nx/\\\u001a,h \t:\u0007φZ\u001a&GQA@58J\u0001D\u001a/D#|>\u0018\u00121:d\u0018zh\u0007Ҁ9kʚ\u0001\u00024IV\u0017-ڦ;?n|C4j\u0003Z<Va74qǇRZ\u0007RSr\u001bvH7ffpS6|4AO`iӠ2[ێM:V\u0013hib\u001fC򆑈kILW\rF!Pj]\u0003hj\nA4t+z7\\|?vi@4YE<\u0016\u0007(\"O7GӴ!fX{{Pk27>Y/~W*$om>\u0010%HB \u001a\u001a\u0010?ȵ,\u001dD\n\u00047t,\u0012'-sLXњz6i/\u0018YQ\u000bD \u001d\u001bu}\u0010k:/&όIԤLo=\f+\f_\u001fBA@t\r'+f0\bp~Fu\f3T'\u0013bF\r-]\u001bia]\u0001,\u000fǜ85\u00101%>Ec--|3/eƲ+,\u0004î2\u001b(+j\u0006Ɠe\f:8\t/DD\u001c㌊ķ\u001bT(,jR3U&x\u0013U\u0011'\u0017cλ\rDwzzd\u0018P\u0015v.)\u000bQ\u001d\r\u0013K\rW\u0018Q\u001cUz\nE\t \rsz\n\nN]֔\u001a[[Ӎ教q߳ה\u0000ddϱ\u001e\u000bn-\r)d\u0017\t/e\bM-\u0019Hq+5\u0012'K\u0013\u0015tB\u001c\u001d)\u0001fD\u001a=xd@\u000bc0eߵ\u0005d1⫣\u0001h-OnjB@=\u001d'\u0001*|\u0000QX%Ě\b@S[2\bM\u0000^\n+*dG\u0012pzy\u0001\\⪕*We[\u0010i\u0004e\u0010<g49Ǡ&CF\bF\u0016j:\b\u0001\u0007p\u0000<\u0013=<4|-@.i\u001a?`\t\"N4ª빡xJfffb\u0010\r\"CO4\u0011Ϩ1V\".iPy,ɲ\u0007hb؉\u0018{3Q!r8\u0011+e j@E[\"2\b*D95̿d\u000b#G)Lӣi@G\u001fhctI\u0001\u001dDۀӷ\b\u001bP1\u0018q+XiW\u000e!_Q~xGl\r\nendstream\rendobj\r19 0 obj\r[18 0 R]\rendobj\r27 0 obj\r<</CreationDate(D:20221115174608-04'00')/Creator(Adobe Illustrator 26.5 \\(Windows\\))/ModDate(D:20221115174608-05'00')/Producer(Adobe PDF library 16.07)/Title(connect-query)>>\rendobj\rxref\r\n0 28\r\n0000000004 65535 f\r\n0000000016 00000 n\r\n0000000147 00000 n\r\n0000031392 00000 n\r\n0000000000 00000 f\r\n0000031443 00000 n\r\n0000000000 00000 f\r\n0000036465 00000 n\r\n0000000000 00000 f\r\n0000000000 00000 f\r\n0000000000 00000 f\r\n0000000000 00000 f\r\n0000000000 00000 f\r\n0000000000 00000 f\r\n0000036538 00000 n\r\n0000036679 00000 n\r\n0000038208 00000 n\r\n0000000000 00000 f\r\n0000036165 00000 n\r\n0000077176 00000 n\r\n0000031797 00000 n\r\n0000036352 00000 n\r\n0000035233 00000 n\r\n0000035603 00000 n\r\n0000035651 00000 n\r\n0000036236 00000 n\r\n0000036267 00000 n\r\n0000077201 00000 n\r\ntrailer\r\n<</Size 28/Root 1 0 R/Info 27 0 R/ID[<6033E0CCD2B580498183EBFA38AF0F65><1C85417C8E6E7F45A66543808DE86DA0>]>>\r\nstartxref\r\n77392\r\n%%EOF\r\n"
  },
  {
    "path": "assets/connect-query_dependency_graph.excalidraw",
    "content": "{\n  \"type\": \"excalidraw\",\n  \"version\": 2,\n  \"source\": \"https://excalidraw.com\",\n  \"elements\": [\n    {\n      \"type\": \"rectangle\",\n      \"version\": 338,\n      \"versionNonce\": 2062451677,\n      \"isDeleted\": false,\n      \"id\": \"XeSFIfHiUS6jxoqpDlWJf\",\n      \"fillStyle\": \"solid\",\n      \"strokeWidth\": 1,\n      \"strokeStyle\": \"dotted\",\n      \"roughness\": 0,\n      \"opacity\": 100,\n      \"angle\": 0,\n      \"x\": 460.8332824707031,\n      \"y\": 499.1667175292969,\n      \"strokeColor\": \"#000000\",\n      \"backgroundColor\": \"#868e96\",\n      \"width\": 258,\n      \"height\": 104.66665649414062,\n      \"seed\": 922502867,\n      \"groupIds\": [],\n      \"roundness\": {\n        \"type\": 3\n      },\n      \"boundElements\": [\n        {\n          \"type\": \"text\",\n          \"id\": \"nCL0iXpxT4jwwx2rTwPB8\"\n        },\n        {\n          \"id\": \"KmuiK-MBdqr2GTx-Jkug_\",\n          \"type\": \"arrow\"\n        }\n      ],\n      \"updated\": 1673457524342,\n      \"link\": null,\n      \"locked\": false\n    },\n    {\n      \"type\": \"text\",\n      \"version\": 281,\n      \"versionNonce\": 922683517,\n      \"isDeleted\": false,\n      \"id\": \"nCL0iXpxT4jwwx2rTwPB8\",\n      \"fillStyle\": \"hachure\",\n      \"strokeWidth\": 1,\n      \"strokeStyle\": \"solid\",\n      \"roughness\": 1,\n      \"opacity\": 100,\n      \"angle\": 0,\n      \"x\": 524.8332824707031,\n      \"y\": 539.5000457763672,\n      \"strokeColor\": \"#000000\",\n      \"backgroundColor\": \"transparent\",\n      \"width\": 130,\n      \"height\": 24,\n      \"seed\": 543194013,\n      \"groupIds\": [],\n      \"roundness\": null,\n      \"boundElements\": null,\n      \"updated\": 1673457516212,\n      \"link\": null,\n      \"locked\": false,\n      \"fontSize\": 20,\n      \"fontFamily\": 3,\n      \"text\": \"Connect-Web\",\n      \"baseline\": 19,\n      \"textAlign\": \"center\",\n      \"verticalAlign\": \"middle\",\n      \"containerId\": \"XeSFIfHiUS6jxoqpDlWJf\",\n      \"originalText\": \"Connect-Web\"\n    },\n    {\n      \"type\": \"rectangle\",\n      \"version\": 653,\n      \"versionNonce\": 1196429683,\n      \"isDeleted\": false,\n      \"id\": \"HdkWX-Z70zh5w9kpusrjy\",\n      \"fillStyle\": \"solid\",\n      \"strokeWidth\": 1,\n      \"strokeStyle\": \"solid\",\n      \"roughness\": 0,\n      \"opacity\": 100,\n      \"angle\": 0,\n      \"x\": 900,\n      \"y\": 780,\n      \"strokeColor\": \"#000000\",\n      \"backgroundColor\": \"#228be6\",\n      \"width\": 258,\n      \"height\": 104.66665649414062,\n      \"seed\": 1886852829,\n      \"groupIds\": [],\n      \"roundness\": null,\n      \"boundElements\": [\n        {\n          \"type\": \"text\",\n          \"id\": \"v4h5RDwi8qngLrgWkXvyY\"\n        },\n        {\n          \"id\": \"gvjIhXtSYcnwYBZ2oDDpS\",\n          \"type\": \"arrow\"\n        },\n        {\n          \"id\": \"7wHm2jFQS6ITLYsjqcOU2\",\n          \"type\": \"arrow\"\n        },\n        {\n          \"id\": \"KmuiK-MBdqr2GTx-Jkug_\",\n          \"type\": \"arrow\"\n        },\n        {\n          \"id\": \"a_FVwdNlnqR-gZIKraQ74\",\n          \"type\": \"arrow\"\n        },\n        {\n          \"id\": \"FvGaYurosrW130jE07qnK\",\n          \"type\": \"arrow\"\n        },\n        {\n          \"id\": \"PAWB2iARdE5gRjLXwnX02\",\n          \"type\": \"arrow\"\n        }\n      ],\n      \"updated\": 1673457529506,\n      \"link\": null,\n      \"locked\": false\n    },\n    {\n      \"type\": \"text\",\n      \"version\": 629,\n      \"versionNonce\": 1087894771,\n      \"isDeleted\": false,\n      \"id\": \"v4h5RDwi8qngLrgWkXvyY\",\n      \"fillStyle\": \"hachure\",\n      \"strokeWidth\": 1,\n      \"strokeStyle\": \"solid\",\n      \"roughness\": 1,\n      \"opacity\": 100,\n      \"angle\": 0,\n      \"x\": 917,\n      \"y\": 820.3333282470703,\n      \"strokeColor\": \"#000000\",\n      \"backgroundColor\": \"transparent\",\n      \"width\": 224,\n      \"height\": 24,\n      \"seed\": 224714451,\n      \"groupIds\": [],\n      \"roundness\": null,\n      \"boundElements\": null,\n      \"updated\": 1673456334543,\n      \"link\": null,\n      \"locked\": false,\n      \"fontSize\": 20,\n      \"fontFamily\": 3,\n      \"text\": \"Your Generated Code\",\n      \"baseline\": 19,\n      \"textAlign\": \"center\",\n      \"verticalAlign\": \"middle\",\n      \"containerId\": \"HdkWX-Z70zh5w9kpusrjy\",\n      \"originalText\": \"Your Generated Code\"\n    },\n    {\n      \"type\": \"rectangle\",\n      \"version\": 539,\n      \"versionNonce\": 1221815059,\n      \"isDeleted\": false,\n      \"id\": \"1QmxoknneXyizwjmTBfsW\",\n      \"fillStyle\": \"solid\",\n      \"strokeWidth\": 1,\n      \"strokeStyle\": \"solid\",\n      \"roughness\": 0,\n      \"opacity\": 100,\n      \"angle\": 0,\n      \"x\": 900,\n      \"y\": 1060,\n      \"strokeColor\": \"#000000\",\n      \"backgroundColor\": \"#228be6\",\n      \"width\": 258,\n      \"height\": 104.66665649414062,\n      \"seed\": 579482429,\n      \"groupIds\": [],\n      \"roundness\": null,\n      \"boundElements\": [\n        {\n          \"type\": \"text\",\n          \"id\": \"TqMtSvn1VfRhyRcNsGcbp\"\n        },\n        {\n          \"id\": \"I_CLj4w8V5pobtEXl2Buj\",\n          \"type\": \"arrow\"\n        },\n        {\n          \"id\": \"7wHm2jFQS6ITLYsjqcOU2\",\n          \"type\": \"arrow\"\n        }\n      ],\n      \"updated\": 1673457529506,\n      \"link\": null,\n      \"locked\": false\n    },\n    {\n      \"type\": \"text\",\n      \"version\": 524,\n      \"versionNonce\": 512941715,\n      \"isDeleted\": false,\n      \"id\": \"TqMtSvn1VfRhyRcNsGcbp\",\n      \"fillStyle\": \"hachure\",\n      \"strokeWidth\": 1,\n      \"strokeStyle\": \"solid\",\n      \"roughness\": 1,\n      \"opacity\": 100,\n      \"angle\": 0,\n      \"x\": 923,\n      \"y\": 1100.3333282470703,\n      \"strokeColor\": \"#000000\",\n      \"backgroundColor\": \"transparent\",\n      \"width\": 212,\n      \"height\": 24,\n      \"seed\": 1530453501,\n      \"groupIds\": [],\n      \"roundness\": null,\n      \"boundElements\": null,\n      \"updated\": 1673456334543,\n      \"link\": null,\n      \"locked\": false,\n      \"fontSize\": 20,\n      \"fontFamily\": 3,\n      \"text\": \"Your Frontend Code\",\n      \"baseline\": 19,\n      \"textAlign\": \"center\",\n      \"verticalAlign\": \"middle\",\n      \"containerId\": \"1QmxoknneXyizwjmTBfsW\",\n      \"originalText\": \"Your Frontend Code\"\n    },\n    {\n      \"type\": \"rectangle\",\n      \"version\": 453,\n      \"versionNonce\": 629932093,\n      \"isDeleted\": false,\n      \"id\": \"70r-ffCEpPw4jZ47fTXY6\",\n      \"fillStyle\": \"solid\",\n      \"strokeWidth\": 1,\n      \"strokeStyle\": \"dotted\",\n      \"roughness\": 0,\n      \"opacity\": 100,\n      \"angle\": 0,\n      \"x\": 1340,\n      \"y\": 220,\n      \"strokeColor\": \"#000000\",\n      \"backgroundColor\": \"#868e96\",\n      \"width\": 258,\n      \"height\": 104.66665649414062,\n      \"seed\": 1410462835,\n      \"groupIds\": [],\n      \"roundness\": {\n        \"type\": 3\n      },\n      \"boundElements\": [\n        {\n          \"type\": \"text\",\n          \"id\": \"zgjnIw46XBD2g0GOjB_qZ\"\n        },\n        {\n          \"id\": \"pq6WADDyw4BOp77bAngzy\",\n          \"type\": \"arrow\"\n        },\n        {\n          \"id\": \"EUUJPfgFQLQKC9QmFn2Hj\",\n          \"type\": \"arrow\"\n        }\n      ],\n      \"updated\": 1673457524342,\n      \"link\": null,\n      \"locked\": false\n    },\n    {\n      \"type\": \"text\",\n      \"version\": 401,\n      \"versionNonce\": 75469875,\n      \"isDeleted\": false,\n      \"id\": \"zgjnIw46XBD2g0GOjB_qZ\",\n      \"fillStyle\": \"hachure\",\n      \"strokeWidth\": 1,\n      \"strokeStyle\": \"solid\",\n      \"roughness\": 1,\n      \"opacity\": 100,\n      \"angle\": 0,\n      \"x\": 1404,\n      \"y\": 260.3333282470703,\n      \"strokeColor\": \"#000000\",\n      \"backgroundColor\": \"transparent\",\n      \"width\": 130,\n      \"height\": 24,\n      \"seed\": 825000477,\n      \"groupIds\": [],\n      \"roundness\": null,\n      \"boundElements\": null,\n      \"updated\": 1673456334543,\n      \"link\": null,\n      \"locked\": false,\n      \"fontSize\": 20,\n      \"fontFamily\": 3,\n      \"text\": \"Protobuf-ES\",\n      \"baseline\": 19,\n      \"textAlign\": \"center\",\n      \"verticalAlign\": \"middle\",\n      \"containerId\": \"70r-ffCEpPw4jZ47fTXY6\",\n      \"originalText\": \"Protobuf-ES\"\n    },\n    {\n      \"type\": \"rectangle\",\n      \"version\": 552,\n      \"versionNonce\": 737865885,\n      \"isDeleted\": false,\n      \"id\": \"lN_Z7SPGJvUJ1_qQgp_my\",\n      \"fillStyle\": \"solid\",\n      \"strokeWidth\": 1,\n      \"strokeStyle\": \"dotted\",\n      \"roughness\": 0,\n      \"opacity\": 100,\n      \"angle\": 0,\n      \"x\": 900.8332824707031,\n      \"y\": 499.1667175292969,\n      \"strokeColor\": \"#000000\",\n      \"backgroundColor\": \"#868e96\",\n      \"width\": 258,\n      \"height\": 104.66665649414062,\n      \"seed\": 1231089171,\n      \"groupIds\": [],\n      \"roundness\": {\n        \"type\": 3\n      },\n      \"boundElements\": [\n        {\n          \"type\": \"text\",\n          \"id\": \"6HsLOBS0-yHGej94R9uAN\"\n        },\n        {\n          \"id\": \"gvjIhXtSYcnwYBZ2oDDpS\",\n          \"type\": \"arrow\"\n        },\n        {\n          \"id\": \"pq6WADDyw4BOp77bAngzy\",\n          \"type\": \"arrow\"\n        },\n        {\n          \"id\": \"FvGaYurosrW130jE07qnK\",\n          \"type\": \"arrow\"\n        },\n        {\n          \"id\": \"a_FVwdNlnqR-gZIKraQ74\",\n          \"type\": \"arrow\"\n        },\n        {\n          \"id\": \"EUUJPfgFQLQKC9QmFn2Hj\",\n          \"type\": \"arrow\"\n        }\n      ],\n      \"updated\": 1673457524342,\n      \"link\": null,\n      \"locked\": false\n    },\n    {\n      \"type\": \"text\",\n      \"version\": 541,\n      \"versionNonce\": 1575669053,\n      \"isDeleted\": false,\n      \"id\": \"6HsLOBS0-yHGej94R9uAN\",\n      \"fillStyle\": \"hachure\",\n      \"strokeWidth\": 1,\n      \"strokeStyle\": \"solid\",\n      \"roughness\": 1,\n      \"opacity\": 100,\n      \"angle\": 0,\n      \"x\": 953.3332824707031,\n      \"y\": 527.5000457763672,\n      \"strokeColor\": \"#000000\",\n      \"backgroundColor\": \"transparent\",\n      \"width\": 153,\n      \"height\": 48,\n      \"seed\": 543020243,\n      \"groupIds\": [],\n      \"roundness\": null,\n      \"boundElements\": null,\n      \"updated\": 1673457516213,\n      \"link\": null,\n      \"locked\": false,\n      \"fontSize\": 20,\n      \"fontFamily\": 3,\n      \"text\": \"protoc-gen-\\nconnect-query\",\n      \"baseline\": 43,\n      \"textAlign\": \"center\",\n      \"verticalAlign\": \"middle\",\n      \"containerId\": \"lN_Z7SPGJvUJ1_qQgp_my\",\n      \"originalText\": \"protoc-gen-\\nconnect-query\"\n    },\n    {\n      \"type\": \"rectangle\",\n      \"version\": 537,\n      \"versionNonce\": 2079118589,\n      \"isDeleted\": false,\n      \"id\": \"IJST3a9MULbY3nKP5O-vj\",\n      \"fillStyle\": \"solid\",\n      \"strokeWidth\": 1,\n      \"strokeStyle\": \"dotted\",\n      \"roughness\": 0,\n      \"opacity\": 100,\n      \"angle\": 0,\n      \"x\": 1340,\n      \"y\": 780,\n      \"strokeColor\": \"#000000\",\n      \"backgroundColor\": \"#868e96\",\n      \"width\": 258,\n      \"height\": 104.66665649414062,\n      \"seed\": 1507832755,\n      \"groupIds\": [],\n      \"roundness\": {\n        \"type\": 3\n      },\n      \"boundElements\": [\n        {\n          \"type\": \"text\",\n          \"id\": \"pmTReKQQCE0eqd4B1ZO4t\"\n        },\n        {\n          \"id\": \"I_CLj4w8V5pobtEXl2Buj\",\n          \"type\": \"arrow\"\n        },\n        {\n          \"id\": \"7wHm2jFQS6ITLYsjqcOU2\",\n          \"type\": \"arrow\"\n        }\n      ],\n      \"updated\": 1673457524342,\n      \"link\": null,\n      \"locked\": false\n    },\n    {\n      \"type\": \"text\",\n      \"version\": 525,\n      \"versionNonce\": 476151059,\n      \"isDeleted\": false,\n      \"id\": \"pmTReKQQCE0eqd4B1ZO4t\",\n      \"fillStyle\": \"hachure\",\n      \"strokeWidth\": 1,\n      \"strokeStyle\": \"solid\",\n      \"roughness\": 1,\n      \"opacity\": 100,\n      \"angle\": 0,\n      \"x\": 1386.5,\n      \"y\": 820.3333282470703,\n      \"strokeColor\": \"#000000\",\n      \"backgroundColor\": \"transparent\",\n      \"width\": 165,\n      \"height\": 24,\n      \"seed\": 433861949,\n      \"groupIds\": [],\n      \"roundness\": null,\n      \"boundElements\": null,\n      \"updated\": 1673456334543,\n      \"link\": null,\n      \"locked\": false,\n      \"fontSize\": 20,\n      \"fontFamily\": 3,\n      \"text\": \"TanStack Query\",\n      \"baseline\": 19,\n      \"textAlign\": \"center\",\n      \"verticalAlign\": \"middle\",\n      \"containerId\": \"IJST3a9MULbY3nKP5O-vj\",\n      \"originalText\": \"TanStack Query\"\n    },\n    {\n      \"type\": \"arrow\",\n      \"version\": 404,\n      \"versionNonce\": 1650651357,\n      \"isDeleted\": false,\n      \"id\": \"KmuiK-MBdqr2GTx-Jkug_\",\n      \"fillStyle\": \"hachure\",\n      \"strokeWidth\": 1,\n      \"strokeStyle\": \"solid\",\n      \"roughness\": 1,\n      \"opacity\": 100,\n      \"angle\": 0,\n      \"x\": 737.6617093328613,\n      \"y\": 609.239365369029,\n      \"strokeColor\": \"#1864ab\",\n      \"backgroundColor\": \"transparent\",\n      \"width\": 152.24842287378317,\n      \"height\": 159.87055354799793,\n      \"seed\": 458946877,\n      \"groupIds\": [],\n      \"roundness\": null,\n      \"boundElements\": [\n        {\n          \"type\": \"text\",\n          \"id\": \"LwfPx1xIn8ViH6r4EKaCf\"\n        }\n      ],\n      \"updated\": 1673457516212,\n      \"link\": null,\n      \"locked\": false,\n      \"startBinding\": {\n        \"elementId\": \"XeSFIfHiUS6jxoqpDlWJf\",\n        \"focus\": -0.5197748421647741,\n        \"gap\": 19.589139861980925\n      },\n      \"endBinding\": {\n        \"elementId\": \"HdkWX-Z70zh5w9kpusrjy\",\n        \"focus\": -0.4410732002860223,\n        \"gap\": 14.845851207698502\n      },\n      \"lastCommittedPoint\": null,\n      \"startArrowhead\": null,\n      \"endArrowhead\": \"arrow\",\n      \"points\": [\n        [\n          0,\n          0\n        ],\n        [\n          152.24842287378317,\n          159.87055354799793\n        ]\n      ]\n    },\n    {\n      \"id\": \"LwfPx1xIn8ViH6r4EKaCf\",\n      \"type\": \"text\",\n      \"x\": 758.6592881134363,\n      \"y\": 675.748149562487,\n      \"width\": 106,\n      \"height\": 24,\n      \"angle\": 0,\n      \"strokeColor\": \"#1864ab\",\n      \"backgroundColor\": \"transparent\",\n      \"fillStyle\": \"hachure\",\n      \"strokeWidth\": 1,\n      \"strokeStyle\": \"solid\",\n      \"roughness\": 1,\n      \"opacity\": 100,\n      \"groupIds\": [],\n      \"roundness\": null,\n      \"seed\": 1474013971,\n      \"version\": 34,\n      \"versionNonce\": 589494973,\n      \"isDeleted\": false,\n      \"boundElements\": null,\n      \"updated\": 1673456334544,\n      \"link\": null,\n      \"locked\": false,\n      \"text\": \"Transport\",\n      \"fontSize\": 20,\n      \"fontFamily\": 3,\n      \"textAlign\": \"center\",\n      \"verticalAlign\": \"middle\",\n      \"baseline\": 19,\n      \"containerId\": \"KmuiK-MBdqr2GTx-Jkug_\",\n      \"originalText\": \"Transport\"\n    },\n    {\n      \"type\": \"arrow\",\n      \"version\": 123,\n      \"versionNonce\": 1761090973,\n      \"isDeleted\": false,\n      \"id\": \"gvjIhXtSYcnwYBZ2oDDpS\",\n      \"fillStyle\": \"hachure\",\n      \"strokeWidth\": 1,\n      \"strokeStyle\": \"solid\",\n      \"roughness\": 1,\n      \"opacity\": 100,\n      \"angle\": 0,\n      \"x\": 1021.2470991923436,\n      \"y\": 618.9294060114771,\n      \"strokeColor\": \"#1864ab\",\n      \"backgroundColor\": \"transparent\",\n      \"width\": 0.37181829465941973,\n      \"height\": 140.83328247070312,\n      \"seed\": 633861949,\n      \"groupIds\": [],\n      \"roundness\": null,\n      \"boundElements\": [],\n      \"updated\": 1673457516213,\n      \"link\": null,\n      \"locked\": false,\n      \"startBinding\": {\n        \"elementId\": \"lN_Z7SPGJvUJ1_qQgp_my\",\n        \"focus\": 0.06439858402412948,\n        \"gap\": 15.096031988039613\n      },\n      \"endBinding\": {\n        \"elementId\": \"HdkWX-Z70zh5w9kpusrjy\",\n        \"focus\": -0.06439858402412948,\n        \"gap\": 20.237311517819762\n      },\n      \"lastCommittedPoint\": null,\n      \"startArrowhead\": null,\n      \"endArrowhead\": \"arrow\",\n      \"points\": [\n        [\n          0,\n          0\n        ],\n        [\n          -0.37181829465941973,\n          140.83328247070312\n        ]\n      ]\n    },\n    {\n      \"type\": \"arrow\",\n      \"version\": 426,\n      \"versionNonce\": 1592209277,\n      \"isDeleted\": false,\n      \"id\": \"I_CLj4w8V5pobtEXl2Buj\",\n      \"fillStyle\": \"hachure\",\n      \"strokeWidth\": 1,\n      \"strokeStyle\": \"solid\",\n      \"roughness\": 1,\n      \"opacity\": 100,\n      \"angle\": 0,\n      \"x\": 1323.7183536001407,\n      \"y\": 896.2816463998595,\n      \"strokeColor\": \"#1864ab\",\n      \"backgroundColor\": \"transparent\",\n      \"width\": 149.19417890388058,\n      \"height\": 149.19417890388058,\n      \"seed\": 699791827,\n      \"groupIds\": [],\n      \"roundness\": null,\n      \"boundElements\": [\n        {\n          \"type\": \"text\",\n          \"id\": \"CUlnnQd_zqWGo4jP9YXIQ\"\n        }\n      ],\n      \"updated\": 1673456334544,\n      \"link\": null,\n      \"locked\": false,\n      \"startBinding\": {\n        \"elementId\": \"IJST3a9MULbY3nKP5O-vj\",\n        \"focus\": 0.44852939629637206,\n        \"gap\": 20\n      },\n      \"endBinding\": {\n        \"elementId\": \"1QmxoknneXyizwjmTBfsW\",\n        \"focus\": 0.4338235696294328,\n        \"gap\": 22\n      },\n      \"lastCommittedPoint\": null,\n      \"startArrowhead\": null,\n      \"endArrowhead\": \"arrow\",\n      \"points\": [\n        [\n          0,\n          0\n        ],\n        [\n          -149.19417890388058,\n          149.19417890388058\n        ]\n      ]\n    },\n    {\n      \"id\": \"CUlnnQd_zqWGo4jP9YXIQ\",\n      \"type\": \"text\",\n      \"x\": 1184.1212641482005,\n      \"y\": 958.8787358517998,\n      \"width\": 130,\n      \"height\": 24,\n      \"angle\": 0,\n      \"strokeColor\": \"#1864ab\",\n      \"backgroundColor\": \"transparent\",\n      \"fillStyle\": \"hachure\",\n      \"strokeWidth\": 1,\n      \"strokeStyle\": \"solid\",\n      \"roughness\": 1,\n      \"opacity\": 100,\n      \"groupIds\": [],\n      \"roundness\": null,\n      \"seed\": 1784188211,\n      \"version\": 35,\n      \"versionNonce\": 1241731795,\n      \"isDeleted\": false,\n      \"boundElements\": null,\n      \"updated\": 1673456334544,\n      \"link\": null,\n      \"locked\": false,\n      \"text\": \"Query Logic\",\n      \"fontSize\": 20,\n      \"fontFamily\": 3,\n      \"textAlign\": \"center\",\n      \"verticalAlign\": \"middle\",\n      \"baseline\": 19,\n      \"containerId\": \"I_CLj4w8V5pobtEXl2Buj\",\n      \"originalText\": \"Query Logic\"\n    },\n    {\n      \"type\": \"arrow\",\n      \"version\": 347,\n      \"versionNonce\": 173506675,\n      \"isDeleted\": false,\n      \"id\": \"7wHm2jFQS6ITLYsjqcOU2\",\n      \"fillStyle\": \"hachure\",\n      \"strokeWidth\": 1,\n      \"strokeStyle\": \"solid\",\n      \"roughness\": 1,\n      \"opacity\": 100,\n      \"angle\": 0,\n      \"x\": 1020,\n      \"y\": 900,\n      \"strokeColor\": \"#1864ab\",\n      \"backgroundColor\": \"transparent\",\n      \"width\": 0,\n      \"height\": 140,\n      \"seed\": 84359645,\n      \"groupIds\": [],\n      \"roundness\": null,\n      \"boundElements\": [\n        {\n          \"type\": \"text\",\n          \"id\": \"LHppZw4mGtiNgeBRWCQIc\"\n        }\n      ],\n      \"updated\": 1673456334544,\n      \"link\": null,\n      \"locked\": false,\n      \"startBinding\": {\n        \"elementId\": \"HdkWX-Z70zh5w9kpusrjy\",\n        \"focus\": 0.06976744186046512,\n        \"gap\": 15.333343505859375\n      },\n      \"endBinding\": {\n        \"elementId\": \"1QmxoknneXyizwjmTBfsW\",\n        \"focus\": -0.06976744186046512,\n        \"gap\": 20\n      },\n      \"lastCommittedPoint\": null,\n      \"startArrowhead\": null,\n      \"endArrowhead\": \"arrow\",\n      \"points\": [\n        [\n          0,\n          0\n        ],\n        [\n          0,\n          140\n        ]\n      ]\n    },\n    {\n      \"id\": \"LHppZw4mGtiNgeBRWCQIc\",\n      \"type\": \"text\",\n      \"x\": 943.5,\n      \"y\": 958,\n      \"width\": 153,\n      \"height\": 24,\n      \"angle\": 0,\n      \"strokeColor\": \"#1864ab\",\n      \"backgroundColor\": \"transparent\",\n      \"fillStyle\": \"hachure\",\n      \"strokeWidth\": 1,\n      \"strokeStyle\": \"solid\",\n      \"roughness\": 1,\n      \"opacity\": 100,\n      \"groupIds\": [],\n      \"roundness\": null,\n      \"seed\": 687336477,\n      \"version\": 37,\n      \"versionNonce\": 154481725,\n      \"isDeleted\": false,\n      \"boundElements\": null,\n      \"updated\": 1673456334544,\n      \"link\": null,\n      \"locked\": false,\n      \"text\": \"Query Helpers\",\n      \"fontSize\": 20,\n      \"fontFamily\": 3,\n      \"textAlign\": \"center\",\n      \"verticalAlign\": \"middle\",\n      \"baseline\": 19,\n      \"containerId\": \"7wHm2jFQS6ITLYsjqcOU2\",\n      \"originalText\": \"Query Helpers\"\n    },\n    {\n      \"type\": \"arrow\",\n      \"version\": 1349,\n      \"versionNonce\": 1522295293,\n      \"isDeleted\": false,\n      \"id\": \"pq6WADDyw4BOp77bAngzy\",\n      \"fillStyle\": \"hachure\",\n      \"strokeWidth\": 1,\n      \"strokeStyle\": \"solid\",\n      \"roughness\": 1,\n      \"opacity\": 100,\n      \"angle\": 0,\n      \"x\": 1323.6385511190695,\n      \"y\": 336.1689601989077,\n      \"strokeColor\": \"#1864ab\",\n      \"backgroundColor\": \"transparent\",\n      \"width\": 148.31503045010072,\n      \"height\": 148.4350637552135,\n      \"seed\": 1060741971,\n      \"groupIds\": [],\n      \"roundness\": null,\n      \"boundElements\": [],\n      \"updated\": 1673457516213,\n      \"link\": null,\n      \"locked\": false,\n      \"startBinding\": {\n        \"elementId\": \"70r-ffCEpPw4jZ47fTXY6\",\n        \"focus\": 0.44852939629637206,\n        \"gap\": 20\n      },\n      \"endBinding\": {\n        \"elementId\": \"lN_Z7SPGJvUJ1_qQgp_my\",\n        \"focus\": 0.4338235696294328,\n        \"gap\": 22\n      },\n      \"lastCommittedPoint\": null,\n      \"startArrowhead\": null,\n      \"endArrowhead\": \"arrow\",\n      \"points\": [\n        [\n          0,\n          0\n        ],\n        [\n          -148.31503045010072,\n          148.4350637552135\n        ]\n      ]\n    },\n    {\n      \"type\": \"rectangle\",\n      \"version\": 774,\n      \"versionNonce\": 1357065565,\n      \"isDeleted\": false,\n      \"id\": \"wmmX8X0PhUxG4APAQUfdA\",\n      \"fillStyle\": \"solid\",\n      \"strokeWidth\": 1,\n      \"strokeStyle\": \"dotted\",\n      \"roughness\": 0,\n      \"opacity\": 100,\n      \"angle\": 0,\n      \"x\": 1340,\n      \"y\": 500,\n      \"strokeColor\": \"#000000\",\n      \"backgroundColor\": \"#868e96\",\n      \"width\": 258,\n      \"height\": 104.66665649414062,\n      \"seed\": 632603987,\n      \"groupIds\": [],\n      \"roundness\": {\n        \"type\": 3\n      },\n      \"boundElements\": [\n        {\n          \"type\": \"text\",\n          \"id\": \"o8v54ziV3hNiqpchzZcem\"\n        },\n        {\n          \"id\": \"FvGaYurosrW130jE07qnK\",\n          \"type\": \"arrow\"\n        },\n        {\n          \"id\": \"-w3ngGHZOH7S7mmdmHwqP\",\n          \"type\": \"arrow\"\n        },\n        {\n          \"id\": \"EUUJPfgFQLQKC9QmFn2Hj\",\n          \"type\": \"arrow\"\n        }\n      ],\n      \"updated\": 1673457524342,\n      \"link\": null,\n      \"locked\": false\n    },\n    {\n      \"type\": \"text\",\n      \"version\": 773,\n      \"versionNonce\": 1171851517,\n      \"isDeleted\": false,\n      \"id\": \"o8v54ziV3hNiqpchzZcem\",\n      \"fillStyle\": \"hachure\",\n      \"strokeWidth\": 1,\n      \"strokeStyle\": \"solid\",\n      \"roughness\": 1,\n      \"opacity\": 100,\n      \"angle\": 0,\n      \"x\": 1404,\n      \"y\": 528.3333282470703,\n      \"strokeColor\": \"#000000\",\n      \"backgroundColor\": \"transparent\",\n      \"width\": 130,\n      \"height\": 48,\n      \"seed\": 1027074227,\n      \"groupIds\": [],\n      \"roundness\": null,\n      \"boundElements\": null,\n      \"updated\": 1673456334544,\n      \"link\": null,\n      \"locked\": false,\n      \"fontSize\": 20,\n      \"fontFamily\": 3,\n      \"text\": \"protoc-gen-\\nes\",\n      \"baseline\": 43,\n      \"textAlign\": \"center\",\n      \"verticalAlign\": \"middle\",\n      \"containerId\": \"wmmX8X0PhUxG4APAQUfdA\",\n      \"originalText\": \"protoc-gen-\\nes\"\n    },\n    {\n      \"type\": \"arrow\",\n      \"version\": 1343,\n      \"versionNonce\": 1725288787,\n      \"isDeleted\": false,\n      \"id\": \"FvGaYurosrW130jE07qnK\",\n      \"fillStyle\": \"hachure\",\n      \"strokeWidth\": 1,\n      \"strokeStyle\": \"solid\",\n      \"roughness\": 1,\n      \"opacity\": 100,\n      \"angle\": 0,\n      \"x\": 1320,\n      \"y\": 620,\n      \"strokeColor\": \"#1864ab\",\n      \"backgroundColor\": \"transparent\",\n      \"width\": 140,\n      \"height\": 140,\n      \"seed\": 814557597,\n      \"groupIds\": [],\n      \"roundness\": null,\n      \"boundElements\": [],\n      \"updated\": 1673456334544,\n      \"link\": null,\n      \"locked\": false,\n      \"startBinding\": {\n        \"elementId\": \"wmmX8X0PhUxG4APAQUfdA\",\n        \"focus\": 0.44852939629637206,\n        \"gap\": 20\n      },\n      \"endBinding\": {\n        \"elementId\": \"HdkWX-Z70zh5w9kpusrjy\",\n        \"focus\": 0.4338235696294328,\n        \"gap\": 22\n      },\n      \"lastCommittedPoint\": null,\n      \"startArrowhead\": null,\n      \"endArrowhead\": \"arrow\",\n      \"points\": [\n        [\n          0,\n          0\n        ],\n        [\n          -140,\n          140\n        ]\n      ]\n    },\n    {\n      \"type\": \"rectangle\",\n      \"version\": 735,\n      \"versionNonce\": 2049931709,\n      \"isDeleted\": false,\n      \"id\": \"NLMbxwdPMz1O8gu8ku7cT\",\n      \"fillStyle\": \"solid\",\n      \"strokeWidth\": 1,\n      \"strokeStyle\": \"dotted\",\n      \"roughness\": 0,\n      \"opacity\": 100,\n      \"angle\": 0,\n      \"x\": 460,\n      \"y\": 640,\n      \"strokeColor\": \"#000000\",\n      \"backgroundColor\": \"#868e96\",\n      \"width\": 258,\n      \"height\": 104.66665649414062,\n      \"seed\": 70689523,\n      \"groupIds\": [],\n      \"roundness\": {\n        \"type\": 3\n      },\n      \"boundElements\": [\n        {\n          \"type\": \"text\",\n          \"id\": \"FKPW0XXW-xf9J70NAgjEI\"\n        },\n        {\n          \"id\": \"PAWB2iARdE5gRjLXwnX02\",\n          \"type\": \"arrow\"\n        }\n      ],\n      \"updated\": 1673457524342,\n      \"link\": null,\n      \"locked\": false\n    },\n    {\n      \"type\": \"text\",\n      \"version\": 700,\n      \"versionNonce\": 899591613,\n      \"isDeleted\": false,\n      \"id\": \"FKPW0XXW-xf9J70NAgjEI\",\n      \"fillStyle\": \"hachure\",\n      \"strokeWidth\": 1,\n      \"strokeStyle\": \"solid\",\n      \"roughness\": 1,\n      \"opacity\": 100,\n      \"angle\": 0,\n      \"x\": 512.5,\n      \"y\": 680.3333282470703,\n      \"strokeColor\": \"#000000\",\n      \"backgroundColor\": \"transparent\",\n      \"width\": 153,\n      \"height\": 24,\n      \"seed\": 808891261,\n      \"groupIds\": [],\n      \"roundness\": null,\n      \"boundElements\": null,\n      \"updated\": 1673456334544,\n      \"link\": null,\n      \"locked\": false,\n      \"fontSize\": 20,\n      \"fontFamily\": 3,\n      \"text\": \"Connect-Query\",\n      \"baseline\": 19,\n      \"textAlign\": \"center\",\n      \"verticalAlign\": \"middle\",\n      \"containerId\": \"NLMbxwdPMz1O8gu8ku7cT\",\n      \"originalText\": \"Connect-Query\"\n    },\n    {\n      \"type\": \"rectangle\",\n      \"version\": 840,\n      \"versionNonce\": 536514739,\n      \"isDeleted\": false,\n      \"id\": \"58DCEeIe5AGFChCK8Lm0R\",\n      \"fillStyle\": \"solid\",\n      \"strokeWidth\": 1,\n      \"strokeStyle\": \"solid\",\n      \"roughness\": 0,\n      \"opacity\": 100,\n      \"angle\": 0,\n      \"x\": 900,\n      \"y\": 220,\n      \"strokeColor\": \"#000000\",\n      \"backgroundColor\": \"#228be6\",\n      \"width\": 258,\n      \"height\": 104.66665649414062,\n      \"seed\": 1891287965,\n      \"groupIds\": [],\n      \"roundness\": null,\n      \"boundElements\": [\n        {\n          \"type\": \"text\",\n          \"id\": \"vIDwM655KULSinXrVbpHD\"\n        },\n        {\n          \"id\": \"a_FVwdNlnqR-gZIKraQ74\",\n          \"type\": \"arrow\"\n        },\n        {\n          \"id\": \"-w3ngGHZOH7S7mmdmHwqP\",\n          \"type\": \"arrow\"\n        }\n      ],\n      \"updated\": 1673457529506,\n      \"link\": null,\n      \"locked\": false\n    },\n    {\n      \"type\": \"text\",\n      \"version\": 827,\n      \"versionNonce\": 1348202013,\n      \"isDeleted\": false,\n      \"id\": \"vIDwM655KULSinXrVbpHD\",\n      \"fillStyle\": \"hachure\",\n      \"strokeWidth\": 1,\n      \"strokeStyle\": \"solid\",\n      \"roughness\": 1,\n      \"opacity\": 100,\n      \"angle\": 0,\n      \"x\": 946.5,\n      \"y\": 260.3333282470703,\n      \"strokeColor\": \"#000000\",\n      \"backgroundColor\": \"transparent\",\n      \"width\": 165,\n      \"height\": 24,\n      \"seed\": 1728515901,\n      \"groupIds\": [],\n      \"roundness\": null,\n      \"boundElements\": null,\n      \"updated\": 1673456334544,\n      \"link\": null,\n      \"locked\": false,\n      \"fontSize\": 20,\n      \"fontFamily\": 3,\n      \"text\": \"Your Protofile\",\n      \"baseline\": 19,\n      \"textAlign\": \"center\",\n      \"verticalAlign\": \"middle\",\n      \"containerId\": \"58DCEeIe5AGFChCK8Lm0R\",\n      \"originalText\": \"Your Protofile\"\n    },\n    {\n      \"id\": \"a_FVwdNlnqR-gZIKraQ74\",\n      \"type\": \"arrow\",\n      \"x\": 1020,\n      \"y\": 339.1666793823242,\n      \"width\": 0.5369143190519026,\n      \"height\": 139.16671752929688,\n      \"angle\": 0,\n      \"strokeColor\": \"#1864ab\",\n      \"backgroundColor\": \"#ced4da\",\n      \"fillStyle\": \"hachure\",\n      \"strokeWidth\": 1,\n      \"strokeStyle\": \"solid\",\n      \"roughness\": 1,\n      \"opacity\": 100,\n      \"groupIds\": [],\n      \"roundness\": {\n        \"type\": 2\n      },\n      \"seed\": 1769855859,\n      \"version\": 697,\n      \"versionNonce\": 674830941,\n      \"isDeleted\": false,\n      \"boundElements\": [],\n      \"updated\": 1673457516213,\n      \"link\": null,\n      \"locked\": false,\n      \"points\": [\n        [\n          0,\n          0\n        ],\n        [\n          0.5369143190519026,\n          139.16671752929688\n        ]\n      ],\n      \"lastCommittedPoint\": null,\n      \"startBinding\": {\n        \"elementId\": \"58DCEeIe5AGFChCK8Lm0R\",\n        \"focus\": 0.06976744186046512,\n        \"gap\": 14.500022888183594\n      },\n      \"endBinding\": {\n        \"elementId\": \"lN_Z7SPGJvUJ1_qQgp_my\",\n        \"focus\": -0.06976744186046512,\n        \"gap\": 20.83332061767578\n      },\n      \"startArrowhead\": null,\n      \"endArrowhead\": \"arrow\"\n    },\n    {\n      \"type\": \"rectangle\",\n      \"version\": 387,\n      \"versionNonce\": 1626552861,\n      \"isDeleted\": false,\n      \"id\": \"8A9Hj-N3wkhESFIv5cuO9\",\n      \"fillStyle\": \"solid\",\n      \"strokeWidth\": 1,\n      \"strokeStyle\": \"dotted\",\n      \"roughness\": 0,\n      \"opacity\": 100,\n      \"angle\": 0,\n      \"x\": 460,\n      \"y\": 1060,\n      \"strokeColor\": \"#000000\",\n      \"backgroundColor\": \"#868e96\",\n      \"width\": 160,\n      \"height\": 40,\n      \"seed\": 501992595,\n      \"groupIds\": [],\n      \"roundness\": {\n        \"type\": 3\n      },\n      \"boundElements\": [\n        {\n          \"type\": \"text\",\n          \"id\": \"xtKa4RSXNkP5YhJ4M_VYx\"\n        }\n      ],\n      \"updated\": 1673457524342,\n      \"link\": null,\n      \"locked\": false\n    },\n    {\n      \"type\": \"text\",\n      \"version\": 339,\n      \"versionNonce\": 582969149,\n      \"isDeleted\": false,\n      \"id\": \"xtKa4RSXNkP5YhJ4M_VYx\",\n      \"fillStyle\": \"hachure\",\n      \"strokeWidth\": 1,\n      \"strokeStyle\": \"solid\",\n      \"roughness\": 1,\n      \"opacity\": 100,\n      \"angle\": 0,\n      \"x\": 475,\n      \"y\": 1068,\n      \"strokeColor\": \"#000000\",\n      \"backgroundColor\": \"transparent\",\n      \"width\": 130,\n      \"height\": 24,\n      \"seed\": 1601738291,\n      \"groupIds\": [],\n      \"roundness\": null,\n      \"boundElements\": null,\n      \"updated\": 1673456334544,\n      \"link\": null,\n      \"locked\": false,\n      \"fontSize\": 20,\n      \"fontFamily\": 3,\n      \"text\": \"npm package\",\n      \"baseline\": 19,\n      \"textAlign\": \"center\",\n      \"verticalAlign\": \"middle\",\n      \"containerId\": \"8A9Hj-N3wkhESFIv5cuO9\",\n      \"originalText\": \"npm package\"\n    },\n    {\n      \"type\": \"rectangle\",\n      \"version\": 692,\n      \"versionNonce\": 2025551635,\n      \"isDeleted\": false,\n      \"id\": \"kl6tzqBN_O2oPLMieESou\",\n      \"fillStyle\": \"solid\",\n      \"strokeWidth\": 1,\n      \"strokeStyle\": \"solid\",\n      \"roughness\": 1,\n      \"opacity\": 100,\n      \"angle\": 0,\n      \"x\": 460,\n      \"y\": 1120,\n      \"strokeColor\": \"#000000\",\n      \"backgroundColor\": \"#228be6\",\n      \"width\": 160,\n      \"height\": 40,\n      \"seed\": 314591827,\n      \"groupIds\": [],\n      \"roundness\": null,\n      \"boundElements\": [\n        {\n          \"type\": \"text\",\n          \"id\": \"uJxuk7GZFFnxpY8yy_bUC\"\n        }\n      ],\n      \"updated\": 1673456334544,\n      \"link\": null,\n      \"locked\": false\n    },\n    {\n      \"type\": \"text\",\n      \"version\": 683,\n      \"versionNonce\": 472479645,\n      \"isDeleted\": false,\n      \"id\": \"uJxuk7GZFFnxpY8yy_bUC\",\n      \"fillStyle\": \"hachure\",\n      \"strokeWidth\": 1,\n      \"strokeStyle\": \"solid\",\n      \"roughness\": 1,\n      \"opacity\": 100,\n      \"angle\": 0,\n      \"x\": 475,\n      \"y\": 1128,\n      \"strokeColor\": \"#000000\",\n      \"backgroundColor\": \"transparent\",\n      \"width\": 130,\n      \"height\": 24,\n      \"seed\": 805206109,\n      \"groupIds\": [],\n      \"roundness\": null,\n      \"boundElements\": null,\n      \"updated\": 1673456334544,\n      \"link\": null,\n      \"locked\": false,\n      \"fontSize\": 20,\n      \"fontFamily\": 3,\n      \"text\": \"source code\",\n      \"baseline\": 19,\n      \"textAlign\": \"center\",\n      \"verticalAlign\": \"middle\",\n      \"containerId\": \"kl6tzqBN_O2oPLMieESou\",\n      \"originalText\": \"source code\"\n    },\n    {\n      \"type\": \"arrow\",\n      \"version\": 550,\n      \"versionNonce\": 788602035,\n      \"isDeleted\": false,\n      \"id\": \"PAWB2iARdE5gRjLXwnX02\",\n      \"fillStyle\": \"hachure\",\n      \"strokeWidth\": 1,\n      \"strokeStyle\": \"solid\",\n      \"roughness\": 1,\n      \"opacity\": 100,\n      \"angle\": 0,\n      \"x\": 731.2059132037748,\n      \"y\": 750.780397087813,\n      \"strokeColor\": \"#1864ab\",\n      \"backgroundColor\": \"transparent\",\n      \"width\": 148.7940867962252,\n      \"height\": 89.21960291218704,\n      \"seed\": 890429011,\n      \"groupIds\": [],\n      \"roundness\": null,\n      \"boundElements\": [\n        {\n          \"type\": \"text\",\n          \"id\": \"WRx0CxczbENMaHeXeBTVU\"\n        }\n      ],\n      \"updated\": 1673456334545,\n      \"link\": null,\n      \"locked\": false,\n      \"startBinding\": {\n        \"elementId\": \"NLMbxwdPMz1O8gu8ku7cT\",\n        \"focus\": -0.20682688999780358,\n        \"gap\": 14.552455723772255\n      },\n      \"endBinding\": {\n        \"elementId\": \"HdkWX-Z70zh5w9kpusrjy\",\n        \"focus\": -0.7480468885848,\n        \"gap\": 20\n      },\n      \"lastCommittedPoint\": null,\n      \"startArrowhead\": null,\n      \"endArrowhead\": \"arrow\",\n      \"points\": [\n        [\n          0,\n          0\n        ],\n        [\n          148.7940867962252,\n          89.21960291218704\n        ]\n      ]\n    },\n    {\n      \"type\": \"text\",\n      \"version\": 40,\n      \"versionNonce\": 313687037,\n      \"isDeleted\": false,\n      \"id\": \"WRx0CxczbENMaHeXeBTVU\",\n      \"fillStyle\": \"hachure\",\n      \"strokeWidth\": 1,\n      \"strokeStyle\": \"solid\",\n      \"roughness\": 1,\n      \"opacity\": 100,\n      \"angle\": 0,\n      \"x\": 775.6029566018874,\n      \"y\": 783.3901985439065,\n      \"strokeColor\": \"#1864ab\",\n      \"backgroundColor\": \"transparent\",\n      \"width\": 60,\n      \"height\": 24,\n      \"seed\": 13575261,\n      \"groupIds\": [],\n      \"roundness\": null,\n      \"boundElements\": null,\n      \"updated\": 1673456334545,\n      \"link\": null,\n      \"locked\": false,\n      \"fontSize\": 20,\n      \"fontFamily\": 3,\n      \"text\": \"hooks\",\n      \"baseline\": 19,\n      \"textAlign\": \"center\",\n      \"verticalAlign\": \"middle\",\n      \"containerId\": \"PAWB2iARdE5gRjLXwnX02\",\n      \"originalText\": \"hooks\"\n    },\n    {\n      \"type\": \"arrow\",\n      \"version\": 1336,\n      \"versionNonce\": 79760979,\n      \"isDeleted\": false,\n      \"id\": \"-w3ngGHZOH7S7mmdmHwqP\",\n      \"fillStyle\": \"hachure\",\n      \"strokeWidth\": 1,\n      \"strokeStyle\": \"solid\",\n      \"roughness\": 1,\n      \"opacity\": 100,\n      \"angle\": 0,\n      \"x\": 1180,\n      \"y\": 339.1666793823242,\n      \"strokeColor\": \"#1864ab\",\n      \"backgroundColor\": \"#ced4da\",\n      \"width\": 140,\n      \"height\": 140,\n      \"seed\": 417848861,\n      \"groupIds\": [],\n      \"roundness\": {\n        \"type\": 2\n      },\n      \"boundElements\": null,\n      \"updated\": 1673456334545,\n      \"link\": null,\n      \"locked\": false,\n      \"startBinding\": {\n        \"elementId\": \"58DCEeIe5AGFChCK8Lm0R\",\n        \"focus\": -0.46415432661152806,\n        \"gap\": 22\n      },\n      \"endBinding\": {\n        \"elementId\": \"wmmX8X0PhUxG4APAQUfdA\",\n        \"focus\": -0.41819863931427675,\n        \"gap\": 20.83332061767578\n      },\n      \"lastCommittedPoint\": null,\n      \"startArrowhead\": null,\n      \"endArrowhead\": \"arrow\",\n      \"points\": [\n        [\n          0,\n          0\n        ],\n        [\n          140,\n          140\n        ]\n      ]\n    },\n    {\n      \"type\": \"arrow\",\n      \"version\": 1996,\n      \"versionNonce\": 993645971,\n      \"isDeleted\": false,\n      \"id\": \"EUUJPfgFQLQKC9QmFn2Hj\",\n      \"fillStyle\": \"hachure\",\n      \"strokeWidth\": 1,\n      \"strokeStyle\": \"solid\",\n      \"roughness\": 1,\n      \"opacity\": 100,\n      \"angle\": 0,\n      \"x\": 1460,\n      \"y\": 340,\n      \"strokeColor\": \"#1864ab\",\n      \"backgroundColor\": \"transparent\",\n      \"width\": 0,\n      \"height\": 140,\n      \"seed\": 795421171,\n      \"groupIds\": [],\n      \"roundness\": null,\n      \"boundElements\": [],\n      \"updated\": 1673456334545,\n      \"link\": null,\n      \"locked\": false,\n      \"startBinding\": {\n        \"elementId\": \"70r-ffCEpPw4jZ47fTXY6\",\n        \"focus\": 0.06976744186046512,\n        \"gap\": 15.333343505859375\n      },\n      \"endBinding\": {\n        \"elementId\": \"wmmX8X0PhUxG4APAQUfdA\",\n        \"focus\": -0.06976744186046512,\n        \"gap\": 20\n      },\n      \"lastCommittedPoint\": null,\n      \"startArrowhead\": null,\n      \"endArrowhead\": \"arrow\",\n      \"points\": [\n        [\n          0,\n          0\n        ],\n        [\n          0,\n          140\n        ]\n      ]\n    }\n  ],\n  \"appState\": {\n    \"gridSize\": null,\n    \"viewBackgroundColor\": \"#ffffff\"\n  },\n  \"files\": {}\n}"
  },
  {
    "path": "cspell.config.json",
    "content": "{\n  \"words\": [\n    \"Deno\",\n    \"Dimitri\",\n    \"Mitropoulos\",\n    \"Quickstart\",\n    \"Stamm\",\n    \"Timo\",\n    \"Vindaloo\",\n    \"Weizenbaum's\",\n    \"attw\",\n    \"backoffs\",\n    \"bufbuild\",\n    \"codegen\",\n    \"connectquery\",\n    \"connectrpc\",\n    \"connectweb\",\n    \"descriptorset\",\n    \"excalidraw\",\n    \"idempotence\",\n    \"idempotency\",\n    \"inferencing\",\n    \"invalidators\",\n    \"keyof\",\n    \"lcov\",\n    \"nocheck\",\n    \"pnpm\",\n    \"preconfigured\",\n    \"proto\",\n    \"protobuf\",\n    \"protoc\",\n    \"protofile\",\n    \"protoplugin\",\n    \"tanstack\",\n    \"todos\",\n    \"tsdoc\",\n    \"corepack\",\n    \"printables\",\n    \"arethetypeswrong\",\n    \"oneof\",\n    \"typesafe\",\n    \"setversion\",\n    \"getversion\",\n    \"postsetversion\",\n    \"postgenerate\",\n    \"npmjs\"\n  ],\n  \"ignorePaths\": [\n    \"**/*.svg\",\n    \"**/*.ai\",\n    \"**/pnpm-lock.yaml\",\n    \"*.excalidraw\",\n    \"**/gen\",\n    \"**/snapshots\",\n    \"**/*.css\",\n    \"**/*.xml\",\n    \"**/tsconfig.vitest-temp.json\"\n  ]\n}\n"
  },
  {
    "path": "package.json",
    "content": "{\n  \"private\": true,\n  \"name\": \"root\",\n  \"type\": \"module\",\n  \"workspaces\": [\n    \"packages/connect-query-core\",\n    \"packages/connect-query\",\n    \"packages/examples/react/basic\",\n    \"packages/protoc-gen-connect-query\",\n    \"packages/test-utils\"\n  ],\n  \"scripts\": {\n    \"all\": \"turbo run --ui tui build format test lint attw license-header\",\n    \"clean\": \"git clean -Xdf\",\n    \"setversion\": \"node scripts/set-workspace-version.js\",\n    \"getversion\": \"node scripts/find-workspace-version.js\",\n    \"postsetversion\": \"npm run all\",\n    \"release\": \"node scripts/release.js\",\n    \"prerelease\": \"npm run all\",\n    \"format\": \"prettier --write --ignore-unknown '.' '!packages' '!.turbo' '!node_modules'\",\n    \"license-header\": \"license-header --ignore 'packages/**'\",\n    \"lint\": \"eslint --max-warnings 0 . --ignore-pattern 'packages/**' && npm run check:spelling\",\n    \"check:spelling\": \"cspell \\\"**\\\" --gitignore\"\n  },\n  \"packageManager\": \"npm@10.1.0\",\n  \"licenseHeader\": {\n    \"licenseType\": \"apache\",\n    \"yearRange\": \"2021-2023\",\n    \"copyrightHolder\": \"The Connect Authors\"\n  },\n  \"devDependencies\": {\n    \"@bufbuild/license-header\": \"^0.0.4\",\n    \"@types/node\": \"^22.15.29\",\n    \"@typescript-eslint/eslint-plugin\": \"8.33.0\",\n    \"@typescript-eslint/parser\": \"8.33.0\",\n    \"@typescript-eslint/utils\": \"8.33.0\",\n    \"@vitest/ui\": \"^3.2.4\",\n    \"cspell\": \"9.0.2\",\n    \"eslint\": \"8.57.0\",\n    \"eslint-config-prettier\": \"10.1.5\",\n    \"eslint-import-resolver-typescript\": \"^4.4.2\",\n    \"eslint-plugin-eslint-comments\": \"3.2.0\",\n    \"eslint-plugin-import\": \"^2.29.1\",\n    \"eslint-plugin-n\": \"^17.18.0\",\n    \"eslint-plugin-react-hooks\": \"^5.2.0\",\n    \"eslint-plugin-simple-import-sort\": \"^12.1.1\",\n    \"eslint-plugin-vitest\": \"0.5.4\",\n    \"prettier\": \"3.5.3\",\n    \"turbo\": \"^2.5.4\",\n    \"typescript\": \"5.8.3\",\n    \"vitest\": \"^3.2.4\"\n  },\n  \"engineStrict\": true,\n  \"engines\": {\n    \"node\": \">=20\",\n    \"npm\": \">=10.8\"\n  }\n}\n"
  },
  {
    "path": "packages/connect-query/README.md",
    "content": "# @connectrpc/connect-query\n\nThis is the runtime library package for Connect-Query. You'll find its code generator at [@connectrpc/protoc-gen-connect-query](https://www.npmjs.com/package/@connectrpc/protoc-gen-connect-query).\n\nConnect-Query is a wrapper around [TanStack Query](https://tanstack.com/query) (react-query), written in TypeScript and thoroughly tested. It enables effortless communication with servers that speak the [Connect Protocol](https://connectrpc.com/docs/protocol).\n\nTo get started, head over to the [docs](https://github.com/connectrpc/connect-query-es) for a tutorial, or take a look at [our examples](https://github.com/connectrpc/connect-query-es/tree/main/examples).\n"
  },
  {
    "path": "packages/connect-query/package.json",
    "content": "{\n  \"name\": \"@connectrpc/connect-query\",\n  \"version\": \"2.2.0\",\n  \"description\": \"TypeScript-first expansion pack for TanStack Query that gives you Protobuf superpowers.\",\n  \"license\": \"Apache-2.0\",\n  \"repository\": {\n    \"type\": \"git\",\n    \"url\": \"https://github.com/connectrpc/connect-query-es.git\",\n    \"directory\": \"packages/connect-query\"\n  },\n  \"scripts\": {\n    \"prebuild\": \"rm -rf ./dist/*\",\n    \"build\": \"npm run build:cjs && npm run build:esm\",\n    \"build:cjs\": \"tsc --project tsconfig.build.json --module commonjs --verbatimModuleSyntax false --moduleResolution node10 --outDir ./dist/cjs --declaration --declarationDir ./dist/cjs && echo >./dist/cjs/package.json '{\\\"type\\\":\\\"commonjs\\\"}'\",\n    \"build:esm\": \"tsc --project tsconfig.build.json --outDir ./dist/esm --declaration --declarationDir ./dist/esm\",\n    \"test\": \"vitest --run\",\n    \"test:watch\": \"vitest --watch\",\n    \"format\": \"prettier --write --ignore-unknown '.' '!dist'\",\n    \"license-header\": \"license-header\",\n    \"lint\": \"eslint --max-warnings 0 .\",\n    \"attw\": \"attw --pack\"\n  },\n  \"type\": \"module\",\n  \"sideEffects\": false,\n  \"main\": \"./dist/cjs/index.js\",\n  \"exports\": {\n    \".\": {\n      \"import\": \"./dist/esm/index.js\",\n      \"require\": \"./dist/cjs/index.js\"\n    }\n  },\n  \"dependencies\": {\n    \"@connectrpc/connect-query-core\": \"^2.2.0\"\n  },\n  \"devDependencies\": {\n    \"@arethetypeswrong/cli\": \"^0.18.1\",\n    \"@bufbuild/buf\": \"1.54.0\",\n    \"@bufbuild/jest-environment-jsdom\": \"^0.1.1\",\n    \"@bufbuild/protobuf\": \"^2.5.1\",\n    \"@bufbuild/protoc-gen-es\": \"^2.5.1\",\n    \"@connectrpc/connect\": \"^2.0.2\",\n    \"@connectrpc/connect-web\": \"^2.0.2\",\n    \"@tanstack/react-query\": \"^5.79.0\",\n    \"@testing-library/react\": \"^16.3.0\",\n    \"@types/react\": \"^19.1.6\",\n    \"@types/react-dom\": \"^19.1.5\",\n    \"react\": \"^19.1.0\",\n    \"react-dom\": \"^19.1.0\",\n    \"test-utils\": \"*\",\n    \"typescript\": \"^5.8.3\"\n  },\n  \"peerDependencies\": {\n    \"@bufbuild/protobuf\": \"2.x\",\n    \"@connectrpc/connect\": \"^2.0.1\",\n    \"@tanstack/react-query\": \">=5.62.0\",\n    \"react\": \"^18 || ^19\",\n    \"react-dom\": \"^18 || ^19\"\n  },\n  \"files\": [\n    \"dist/**\"\n  ]\n}\n"
  },
  {
    "path": "packages/connect-query/src/call-unary-method.test.ts",
    "content": "// Copyright 2021-2023 The Connect Authors\n//\n// Licensed under the Apache License, Version 2.0 (the \"License\");\n// you may not use this file except in compliance with the License.\n// You may obtain a copy of the License at\n//\n//      http://www.apache.org/licenses/LICENSE-2.0\n//\n// Unless required by applicable law or agreed to in writing, software\n// distributed under the License is distributed on an \"AS IS\" BASIS,\n// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n// See the License for the specific language governing permissions and\n// limitations under the License.\n\nimport { create } from \"@bufbuild/protobuf\";\nimport type { ConnectQueryKey } from \"@connectrpc/connect-query-core\";\nimport {\n  callUnaryMethod,\n  createConnectQueryKey,\n} from \"@connectrpc/connect-query-core\";\nimport type { QueryFunctionContext } from \"@tanstack/react-query\";\nimport { useQueries } from \"@tanstack/react-query\";\nimport { renderHook, waitFor } from \"@testing-library/react\";\nimport { mockEliza } from \"test-utils\";\nimport type { SayRequest } from \"test-utils/gen/eliza_pb.js\";\nimport { ElizaService, SayRequestSchema } from \"test-utils/gen/eliza_pb.js\";\nimport { describe, expect, it } from \"vitest\";\n\nimport { wrapper } from \"./test/test-wrapper.js\";\n\ndescribe(\"callUnaryMethod\", () => {\n  it(\"can be used with useQueries\", async () => {\n    const transport = mockEliza({\n      sentence: \"Response 1\",\n    });\n    const { result } = renderHook(() => {\n      const input: SayRequest = create(SayRequestSchema, {\n        sentence: \"query 1\",\n      });\n      const [query1] = useQueries({\n        queries: [\n          {\n            queryKey: createConnectQueryKey({\n              schema: ElizaService.method.say,\n              input,\n              transport,\n              cardinality: \"finite\",\n            }),\n            queryFn: async ({\n              signal,\n            }: QueryFunctionContext<ConnectQueryKey>) => {\n              const res = await callUnaryMethod(\n                transport,\n                ElizaService.method.say,\n                input,\n                {\n                  signal,\n                },\n              );\n              return res;\n            },\n          },\n        ],\n      });\n      return {\n        query1,\n      };\n    }, wrapper());\n\n    await waitFor(() => {\n      expect(result.current.query1.isSuccess).toBeTruthy();\n    });\n    expect(result.current.query1.data?.sentence).toEqual(\"Response 1\");\n  });\n  it(\"can pass headers through\", async () => {\n    let resolve: () => void;\n    const promise = new Promise<void>((res) => {\n      resolve = res;\n    });\n    const transport = mockEliza(\n      {\n        sentence: \"Response 1\",\n      },\n      false,\n      {\n        router: {\n          interceptors: [\n            (next) => (req) => {\n              expect(req.header.get(\"x-custom-header\")).toEqual(\"custom-value\");\n              resolve();\n              return next(req);\n            },\n          ],\n        },\n      },\n    );\n    const input: SayRequest = create(SayRequestSchema, {\n      sentence: \"query 1\",\n    });\n    const res = await callUnaryMethod(\n      transport,\n      ElizaService.method.say,\n      input,\n      {\n        headers: {\n          \"x-custom-header\": \"custom-value\",\n        },\n      },\n    );\n    await promise;\n    expect(res.sentence).toEqual(\"Response 1\");\n  });\n});\n"
  },
  {
    "path": "packages/connect-query/src/index.ts",
    "content": "// Copyright 2021-2023 The Connect Authors\n//\n// Licensed under the Apache License, Version 2.0 (the \"License\");\n// you may not use this file except in compliance with the License.\n// You may obtain a copy of the License at\n//\n//      http://www.apache.org/licenses/LICENSE-2.0\n//\n// Unless required by applicable law or agreed to in writing, software\n// distributed under the License is distributed on an \"AS IS\" BASIS,\n// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n// See the License for the specific language governing permissions and\n// limitations under the License.\n\nexport * from \"@connectrpc/connect-query-core\";\nexport { useTransport, TransportProvider } from \"./use-transport.js\";\nexport {\n  useInfiniteQuery,\n  useSuspenseInfiniteQuery,\n} from \"./use-infinite-query.js\";\nexport { useQuery, useSuspenseQuery } from \"./use-query.js\";\nexport type { UseMutationOptions } from \"./use-mutation.js\";\nexport { useMutation } from \"./use-mutation.js\";\nexport type { UseInfiniteQueryOptions } from \"./use-infinite-query.js\";\nexport type { UseQueryOptions } from \"./use-query.js\";\n"
  },
  {
    "path": "packages/connect-query/src/test/test-wrapper.tsx",
    "content": "// Copyright 2021-2023 The Connect Authors\n//\n// Licensed under the Apache License, Version 2.0 (the \"License\");\n// you may not use this file except in compliance with the License.\n// You may obtain a copy of the License at\n//\n//      http://www.apache.org/licenses/LICENSE-2.0\n//\n// Unless required by applicable law or agreed to in writing, software\n// distributed under the License is distributed on an \"AS IS\" BASIS,\n// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n// See the License for the specific language governing permissions and\n// limitations under the License.\n\nimport type { Transport } from \"@connectrpc/connect\";\nimport { createConnectTransport } from \"@connectrpc/connect-web\";\nimport type { QueryClientConfig } from \"@tanstack/react-query\";\nimport { QueryClient, QueryClientProvider } from \"@tanstack/react-query\";\nimport type { JSXElementConstructor, PropsWithChildren } from \"react\";\n\nimport { TransportProvider } from \"../use-transport.js\";\n\n/**\n * A utils wrapper that supplies Tanstack Query's `QueryClientProvider` as well as Connect-Query's `TransportProvider`.\n */\nexport const wrapper = (\n  config?: QueryClientConfig,\n  transport = createConnectTransport({\n    baseUrl: \"https://demo.connectrpc.com\",\n  }),\n): {\n  wrapper: JSXElementConstructor<PropsWithChildren>;\n  queryClient: QueryClient;\n  transport: Transport;\n  queryClientWrapper: JSXElementConstructor<PropsWithChildren>;\n} => {\n  const queryClient = new QueryClient(config);\n  return {\n    wrapper: ({ children }) => (\n      <TransportProvider transport={transport}>\n        <QueryClientProvider client={queryClient}>\n          {children}\n        </QueryClientProvider>\n      </TransportProvider>\n    ),\n    queryClient,\n    transport,\n    queryClientWrapper: ({ children }) => (\n      <QueryClientProvider client={queryClient}>{children}</QueryClientProvider>\n    ),\n  };\n};\n"
  },
  {
    "path": "packages/connect-query/src/use-infinite-query.test.ts",
    "content": "// Copyright 2021-2023 The Connect Authors\n//\n// Licensed under the Apache License, Version 2.0 (the \"License\");\n// you may not use this file except in compliance with the License.\n// You may obtain a copy of the License at\n//\n//      http://www.apache.org/licenses/LICENSE-2.0\n//\n// Unless required by applicable law or agreed to in writing, software\n// distributed under the License is distributed on an \"AS IS\" BASIS,\n// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n// See the License for the specific language governing permissions and\n// limitations under the License.\n\nimport { create } from \"@bufbuild/protobuf\";\nimport { createConnectQueryKey } from \"@connectrpc/connect-query-core\";\nimport { QueryCache, skipToken } from \"@tanstack/react-query\";\nimport { renderHook, waitFor } from \"@testing-library/react\";\nimport {\n  mockNestedPaginatedTransport,\n  mockPaginatedTransport,\n} from \"test-utils\";\nimport {\n  ListRequestSchema,\n  ListResponseSchema,\n  ListService,\n} from \"test-utils/gen/list_pb.js\";\nimport { describe, expect, it, vi } from \"vitest\";\n\nimport { wrapper } from \"./test/test-wrapper.js\";\nimport {\n  useInfiniteQuery,\n  useSuspenseInfiniteQuery,\n} from \"./use-infinite-query.js\";\nimport { useQuery } from \"./use-query.js\";\n\n// TODO: maybe create a helper to take a service and method and generate this.\nconst methodDescriptor = ListService.method.list;\nconst nestedMethodDescriptor = ListService.method.nestedList;\n\nconst mockedPaginatedTransport = mockPaginatedTransport();\nconst mockedNestedPaginatedTransport = mockNestedPaginatedTransport();\n\ndescribe(\"useInfiniteQuery\", () => {\n  it(\"can query paginated data\", async () => {\n    const { result } = renderHook(\n      () => {\n        return useInfiniteQuery(\n          methodDescriptor,\n          {\n            page: 0n,\n          },\n          {\n            getNextPageParam: (lastPage) => lastPage.page + 1n,\n            pageParamKey: \"page\",\n          },\n        );\n      },\n      wrapper({}, mockedPaginatedTransport),\n    );\n\n    await waitFor(() => {\n      expect(result.current.isSuccess).toBeTruthy();\n    });\n    expect(result.current.data).toEqual({\n      pageParams: [0n],\n      pages: [\n        create(ListResponseSchema, {\n          items: [\"-2 Item\", \"-1 Item\", \"0 Item\"],\n          page: 0n,\n        }),\n      ],\n    });\n\n    await result.current.fetchNextPage();\n\n    await waitFor(() => {\n      expect(result.current.isFetching).toBeFalsy();\n    });\n\n    expect(result.current.data).toEqual({\n      pageParams: [0n, 1n],\n      pages: [\n        create(ListResponseSchema, {\n          items: [\"-2 Item\", \"-1 Item\", \"0 Item\"],\n          page: 0n,\n        }),\n        create(ListResponseSchema, {\n          items: [\"1 Item\", \"2 Item\", \"3 Item\"],\n          page: 1n,\n        }),\n      ],\n    });\n  });\n\n  it(\"can be disabled with skipToken\", () => {\n    const { result } = renderHook(\n      () => {\n        return useInfiniteQuery(methodDescriptor, skipToken, {\n          getNextPageParam: (lastPage) => lastPage.page + 1n,\n          pageParamKey: \"page\",\n        });\n      },\n      wrapper(undefined, mockedPaginatedTransport),\n    );\n    expect(result.current.isPending).toBeTruthy();\n    expect(result.current.isFetching).toBeFalsy();\n  });\n\n  it(\"can be provided a custom transport\", async () => {\n    const customTransport = mockPaginatedTransport({\n      items: [\"Intercepted!\"],\n      page: 0n,\n    });\n    const { result } = renderHook(\n      () => {\n        return useInfiniteQuery(\n          methodDescriptor,\n          {\n            page: 0n,\n          },\n          {\n            getNextPageParam: (lastPage) => lastPage.page + 1n,\n            pageParamKey: \"page\",\n            transport: customTransport,\n          },\n        );\n      },\n      wrapper({}, mockedPaginatedTransport),\n    );\n    await waitFor(() => {\n      expect(result.current.isSuccess).toBeTruthy();\n    });\n\n    expect(result.current.data?.pages[0].items).toEqual([\"Intercepted!\"]);\n  });\n\n  it(\"can be provided other props for react-query\", () => {\n    const { result } = renderHook(\n      () => {\n        return useInfiniteQuery(\n          methodDescriptor,\n          {\n            page: 0n,\n          },\n          {\n            getNextPageParam: (lastPage) => lastPage.page + 1n,\n            pageParamKey: \"page\",\n            transport: mockPaginatedTransport(undefined, true),\n            placeholderData: {\n              pageParams: [-1n],\n              pages: [\n                create(methodDescriptor.output, {\n                  page: -1n,\n                  items: [],\n                }),\n              ],\n            },\n          },\n        );\n      },\n      wrapper({}, mockedPaginatedTransport),\n    );\n    expect(result.current.data?.pages[0].page).toEqual(-1n);\n  });\n\n  it(\"can be used along with the select\", async () => {\n    const { result } = renderHook(\n      () => {\n        return useInfiniteQuery(\n          methodDescriptor,\n          {\n            page: 0n,\n          },\n          {\n            select: ({ pages, pageParams }) => ({\n              pages: pages.map((p) => p.items.join(\",\")),\n              pageParams: pageParams.map((p) => p?.toString()),\n            }),\n            getNextPageParam: (lastPage) => lastPage.page + 1n,\n            pageParamKey: \"page\",\n          },\n        );\n      },\n      wrapper({}, mockedPaginatedTransport),\n    );\n\n    await waitFor(() => {\n      expect(result.current.isSuccess).toBeTruthy();\n    });\n    expect(result.current.data).toEqual({\n      pageParams: [\"0\"],\n      pages: [\"-2 Item,-1 Item,0 Item\"],\n    });\n\n    await result.current.fetchNextPage();\n\n    await waitFor(() => {\n      expect(result.current.isFetching).toBeFalsy();\n    });\n    expect(result.current.data).toEqual({\n      pageParams: [\"0\", \"1\"],\n      pages: [\"-2 Item,-1 Item,0 Item\", \"1 Item,2 Item,3 Item\"],\n    });\n  });\n\n  it(\"page param doesn't persist to the query cache\", async () => {\n    const { queryClient, ...remainingWrapper } = wrapper(\n      {},\n      mockedPaginatedTransport,\n    );\n    const { result } = renderHook(() => {\n      return useInfiniteQuery(\n        methodDescriptor,\n        {\n          page: 0n,\n        },\n        {\n          getNextPageParam: (lastPage) => lastPage.page + 1n,\n          pageParamKey: \"page\",\n        },\n      );\n    }, remainingWrapper);\n\n    const cache = queryClient.getQueryCache().getAll();\n\n    expect(cache).toHaveLength(1);\n    expect(cache[0].queryKey).toEqual(\n      createConnectQueryKey({\n        schema: methodDescriptor,\n        transport: mockedPaginatedTransport,\n        cardinality: \"infinite\",\n        pageParamKey: \"page\",\n        input: {},\n      }),\n    );\n\n    await waitFor(() => {\n      expect(result.current.isSuccess).toBeTruthy();\n    });\n\n    expect(result.current.data?.pageParams[0]).toEqual(0n);\n  });\n\n  it(\"doesn't share data with a similar non-infinite query\", async () => {\n    const remainingWrapper = wrapper({}, mockedPaginatedTransport);\n    const { result } = renderHook(() => {\n      return useInfiniteQuery(\n        methodDescriptor,\n        {\n          page: 0n,\n        },\n        {\n          getNextPageParam: (lastPage) => lastPage.page + 1n,\n          pageParamKey: \"page\",\n        },\n      );\n    }, remainingWrapper);\n    await waitFor(() => {\n      expect(result.current.isSuccess).toBeTruthy();\n    });\n    expect(result.current.data?.pages[0].items).toHaveLength(3);\n\n    const { result: useQueryResult } = renderHook(() => {\n      return useQuery(methodDescriptor);\n    }, remainingWrapper);\n\n    await waitFor(() => {\n      expect(useQueryResult.current.isSuccess).toBeTruthy();\n    });\n\n    expect(useQueryResult.current.data?.items).toHaveLength(3);\n  });\n\n  it(\"cache can be invalidated with the shared, non-infinite key\", async () => {\n    const onSuccessSpy = vi.fn();\n    const spiedQueryCache = new QueryCache({\n      onSuccess: onSuccessSpy,\n    });\n    const { queryClient, ...remainingWrapper } = wrapper(\n      { queryCache: spiedQueryCache },\n      mockedPaginatedTransport,\n    );\n    const { result } = renderHook(() => {\n      return useInfiniteQuery(\n        methodDescriptor,\n        {\n          page: 0n,\n        },\n        {\n          getNextPageParam: (lastPage) => lastPage.page + 1n,\n          pageParamKey: \"page\",\n        },\n      );\n    }, remainingWrapper);\n\n    await waitFor(() => {\n      expect(result.current.isSuccess).toBeTruthy();\n    });\n\n    expect(onSuccessSpy).toHaveBeenCalledTimes(1);\n\n    await queryClient.invalidateQueries({\n      queryKey: createConnectQueryKey({\n        schema: methodDescriptor,\n        transport: mockedPaginatedTransport,\n        cardinality: undefined,\n        pageParamKey: \"page\",\n        input: {\n          page: 0n,\n        },\n      }),\n    });\n\n    expect(onSuccessSpy).toHaveBeenCalledTimes(2);\n  });\n\n  it(\"cache can be invalidated with a non-exact key\", async () => {\n    const onSuccessSpy = vi.fn();\n    const spiedQueryCache = new QueryCache({\n      onSuccess: onSuccessSpy,\n    });\n    const { queryClient, ...remainingWrapper } = wrapper(\n      { queryCache: spiedQueryCache },\n      mockedPaginatedTransport,\n    );\n    const { result } = renderHook(() => {\n      return useInfiniteQuery(\n        methodDescriptor,\n        {\n          page: 0n,\n        },\n        {\n          getNextPageParam: (lastPage) => lastPage.page + 1n,\n          pageParamKey: \"page\",\n        },\n      );\n    }, remainingWrapper);\n\n    await waitFor(() => {\n      expect(result.current.isSuccess).toBeTruthy();\n    });\n\n    expect(onSuccessSpy).toHaveBeenCalledTimes(1);\n\n    await queryClient.invalidateQueries({\n      exact: false,\n      queryKey: createConnectQueryKey({\n        schema: methodDescriptor,\n        cardinality: \"infinite\",\n      }),\n    });\n\n    expect(onSuccessSpy).toHaveBeenCalledTimes(2);\n  });\n\n  it(\"can query paginated data with a non-zero page param\", async () => {\n    const wrapperOpts = wrapper({}, mockedPaginatedTransport);\n    const { result } = renderHook(() => {\n      return useInfiniteQuery(\n        methodDescriptor,\n        {\n          page: 1n,\n          preview: true,\n        },\n        {\n          getNextPageParam: (lastPage) => lastPage.page + 1n,\n          pageParamKey: \"page\",\n        },\n      );\n    }, wrapperOpts);\n    await waitFor(() => {\n      expect(result.current.isSuccess).toBeTruthy();\n    });\n    expect(result.current.data?.pages[0].items).toEqual([\n      \"1 Item\",\n      \"2 Item\",\n      \"3 Item\",\n    ]);\n    const manuallyCreatedQueryKey = createConnectQueryKey({\n      schema: methodDescriptor,\n      transport: mockedPaginatedTransport,\n      cardinality: \"infinite\",\n      pageParamKey: \"page\",\n      input: create(ListRequestSchema, {\n        preview: true,\n      }),\n    });\n    expect(\n      wrapperOpts.queryClient.getQueryData(manuallyCreatedQueryKey),\n    ).toEqual(result.current.data);\n  });\n\n  it(\"builds nested page input for successive pages\", async () => {\n    const wrapperOpts = wrapper({}, mockedNestedPaginatedTransport);\n    const { result } = renderHook(() => {\n      return useInfiniteQuery(\n        nestedMethodDescriptor,\n        {\n          nested: {\n            page: 1n,\n            preview: true,\n          },\n        },\n        {\n          getNextPageParam: (lastPage) => (lastPage.nested?.page ?? 0n) + 1n,\n          pageParamKey: \"nested.page\",\n        },\n      );\n    }, wrapperOpts);\n\n    await waitFor(() => {\n      expect(result.current.isSuccess).toBeTruthy();\n    });\n\n    expect(result.current.data?.pageParams).toEqual([1n]);\n    expect(result.current.data?.pages.map((page) => page.nested?.page)).toEqual(\n      [1n],\n    );\n\n    await result.current.fetchNextPage();\n    await waitFor(() => {\n      expect(result.current.isFetching).toBeFalsy();\n    });\n\n    await result.current.fetchNextPage();\n    await waitFor(() => {\n      expect(result.current.isFetching).toBeFalsy();\n    });\n\n    expect(result.current.data?.pageParams).toEqual([1n, 2n, 3n]);\n    expect(result.current.data?.pages.map((page) => page.nested?.page)).toEqual(\n      [1n, 2n, 3n],\n    );\n\n    const manuallyCreatedQueryKey = createConnectQueryKey({\n      schema: nestedMethodDescriptor,\n      transport: mockedNestedPaginatedTransport,\n      cardinality: \"infinite\",\n      pageParamKey: \"nested.page\",\n      input: {\n        nested: {\n          page: 1n,\n          preview: true,\n        },\n      },\n    });\n    expect(\n      wrapperOpts.queryClient.getQueryData(manuallyCreatedQueryKey),\n    ).toEqual(result.current.data);\n  });\n});\n\ndescribe(\"useSuspenseInfiniteQuery\", () => {\n  it(\"can query paginated data\", async () => {\n    const { result } = renderHook(\n      () => {\n        return useSuspenseInfiniteQuery(\n          methodDescriptor,\n          {\n            page: 0n,\n          },\n          {\n            getNextPageParam: (lastPage) => lastPage.page + 1n,\n            pageParamKey: \"page\",\n          },\n        );\n      },\n      wrapper({}, mockedPaginatedTransport),\n    );\n\n    await waitFor(() => {\n      expect(result.current.isSuccess).toBeTruthy();\n    });\n    expect(result.current.data).toEqual({\n      pageParams: [0n],\n      pages: [\n        create(ListResponseSchema, {\n          items: [\"-2 Item\", \"-1 Item\", \"0 Item\"],\n          page: 0n,\n        }),\n      ],\n    });\n\n    await result.current.fetchNextPage();\n\n    await waitFor(() => {\n      expect(result.current.isFetching).toBeFalsy();\n    });\n\n    expect(result.current.data).toEqual({\n      pageParams: [0n, 1n],\n      pages: [\n        create(ListResponseSchema, {\n          items: [\"-2 Item\", \"-1 Item\", \"0 Item\"],\n          page: 0n,\n        }),\n        create(ListResponseSchema, {\n          items: [\"1 Item\", \"2 Item\", \"3 Item\"],\n          page: 1n,\n        }),\n      ],\n    });\n  });\n\n  // eslint-disable-next-line vitest/expect-expect -- We are asserting via @ts-expect-error\n  it(\"can not be disabled with skipToken\", () => {\n    renderHook(\n      () => {\n        return useSuspenseInfiniteQuery(\n          methodDescriptor,\n          // @ts-expect-error(2345) skipToken is not allowed\n          skipToken,\n          {\n            getNextPageParam: (lastPage) => lastPage.page + 1n,\n            pageParamKey: \"page\",\n          },\n        );\n      },\n      wrapper({}, mockedPaginatedTransport),\n    );\n  });\n\n  // eslint-disable-next-line vitest/expect-expect -- We are asserting via @ts-expect-error\n  it(\"does not allow excess properties\", () => {\n    renderHook(\n      () => {\n        return useInfiniteQuery(\n          methodDescriptor,\n          {\n            page: 0n,\n            // @ts-expect-error(2345) extra fields should not be allowed\n            extraField: \"extra\",\n          },\n          {\n            getNextPageParam: (lastPage) => lastPage.page + 1n,\n            pageParamKey: \"page\",\n          },\n        );\n      },\n      wrapper({}, mockedPaginatedTransport),\n    );\n  });\n\n  it(\"can pass headers through\", async () => {\n    let resolve: () => void;\n    const promise = new Promise<void>((res) => {\n      resolve = res;\n    });\n    const transport = mockPaginatedTransport(\n      {\n        items: [\"Intercepted!\"],\n        page: 0n,\n      },\n      false,\n      {\n        router: {\n          interceptors: [\n            (next) => (req) => {\n              expect(req.header.get(\"x-custom-header\")).toEqual(\"custom-value\");\n              resolve();\n              return next(req);\n            },\n          ],\n        },\n      },\n    );\n    const { result } = renderHook(() => {\n      return useSuspenseInfiniteQuery(\n        methodDescriptor,\n        {\n          page: 0n,\n        },\n        {\n          getNextPageParam: (lastPage) => lastPage.page + 1n,\n          pageParamKey: \"page\",\n          transport,\n          headers: {\n            \"x-custom-header\": \"custom-value\",\n          },\n        },\n      );\n    }, wrapper({}));\n\n    await waitFor(() => {\n      expect(result.current.isSuccess).toBeTruthy();\n    });\n\n    await promise;\n\n    expect(result.current.data.pages[0].items).toEqual([\"Intercepted!\"]);\n  });\n});\n"
  },
  {
    "path": "packages/connect-query/src/use-infinite-query.ts",
    "content": "// Copyright 2021-2023 The Connect Authors\n//\n// Licensed under the Apache License, Version 2.0 (the \"License\");\n// you may not use this file except in compliance with the License.\n// You may obtain a copy of the License at\n//\n//      http://www.apache.org/licenses/LICENSE-2.0\n//\n// Unless required by applicable law or agreed to in writing, software\n// distributed under the License is distributed on an \"AS IS\" BASIS,\n// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n// See the License for the specific language governing permissions and\n// limitations under the License.\n\nimport type {\n  DescMessage,\n  DescMethodUnary,\n  MessageInitShape,\n  MessageShape,\n} from \"@bufbuild/protobuf\";\nimport type { ConnectError, Transport } from \"@connectrpc/connect\";\nimport type {\n  ConnectInfiniteQueryOptions,\n  ConnectQueryKey,\n  MessageInitWithPageParam,\n  MessagePageParamKey,\n  MessagePageParamValue,\n} from \"@connectrpc/connect-query-core\";\nimport { createInfiniteQueryOptions } from \"@connectrpc/connect-query-core\";\nimport type {\n  InfiniteData,\n  SkipToken,\n  UseInfiniteQueryOptions as TanStackUseInfiniteQueryOptions,\n  UseInfiniteQueryResult,\n  UseSuspenseInfiniteQueryOptions as TanStackUseSuspenseInfiniteQueryOptions,\n  UseSuspenseInfiniteQueryResult,\n} from \"@tanstack/react-query\";\nimport {\n  useInfiniteQuery as tsUseInfiniteQuery,\n  useSuspenseInfiniteQuery as tsUseSuspenseInfiniteQuery,\n} from \"@tanstack/react-query\";\n\nimport { useTransport } from \"./use-transport.js\";\n\n/**\n * Options for useInfiniteQuery\n */\nexport type UseInfiniteQueryOptions<\n  I extends DescMessage,\n  O extends DescMessage,\n  ParamKey extends MessagePageParamKey<MessageInitShape<I>>,\n  SelectOutData = MessageShape<O>,\n  SelectOutPageParam = unknown,\n> = Omit<\n  TanStackUseInfiniteQueryOptions<\n    MessageShape<O>,\n    ConnectError,\n    InfiniteData<SelectOutData, SelectOutPageParam>,\n    ConnectQueryKey<O>,\n    MessagePageParamValue<MessageInitShape<I>, ParamKey>\n  >,\n  \"getNextPageParam\" | \"initialPageParam\" | \"queryFn\" | \"queryKey\"\n> &\n  ConnectInfiniteQueryOptions<I, O, ParamKey> & {\n    /** The transport to be used for the fetching. */\n    transport?: Transport;\n  };\n\n/**\n * Query the method provided. Maps to useInfiniteQuery on tanstack/react-query\n */\nexport function useInfiniteQuery<\n  I extends DescMessage,\n  O extends DescMessage,\n  const ParamKey extends MessagePageParamKey<MessageInitShape<I>>,\n  SelectOutData = MessageShape<O>,\n  SelectOutPageParam = unknown,\n>(\n  schema: DescMethodUnary<I, O>,\n  input: SkipToken | MessageInitWithPageParam<MessageInitShape<I>, ParamKey>,\n  {\n    transport,\n    pageParamKey,\n    getNextPageParam,\n    ...queryOptions\n  }: UseInfiniteQueryOptions<I, O, ParamKey, SelectOutData, SelectOutPageParam>,\n): UseInfiniteQueryResult<\n  InfiniteData<SelectOutData, SelectOutPageParam>,\n  ConnectError\n> {\n  const transportFromCtx = useTransport();\n  const baseOptions = createInfiniteQueryOptions(schema, input, {\n    transport: transport ?? transportFromCtx,\n    getNextPageParam,\n    pageParamKey,\n  });\n  return tsUseInfiniteQuery({\n    ...baseOptions,\n    ...queryOptions,\n  });\n}\n\n/**\n * Options for useSuspenseInfiniteQuery\n */\nexport type UseSuspenseInfiniteQueryOptions<\n  I extends DescMessage,\n  O extends DescMessage,\n  ParamKey extends MessagePageParamKey<MessageInitShape<I>>,\n  SelectOutData = MessageShape<O>,\n  SelectOutPageParam = unknown,\n> = Omit<\n  TanStackUseSuspenseInfiniteQueryOptions<\n    MessageShape<O>,\n    ConnectError,\n    InfiniteData<SelectOutData, SelectOutPageParam>,\n    ConnectQueryKey<O>,\n    MessagePageParamValue<MessageInitShape<I>, ParamKey>\n  >,\n  \"getNextPageParam\" | \"initialPageParam\" | \"queryFn\" | \"queryKey\"\n> &\n  ConnectInfiniteQueryOptions<I, O, ParamKey> & {\n    /** The transport to be used for the fetching. */\n    transport?: Transport;\n  };\n\n/**\n * Query the method provided. Maps to useSuspenseInfiniteQuery on tanstack/react-query\n */\nexport function useSuspenseInfiniteQuery<\n  I extends DescMessage,\n  O extends DescMessage,\n  const ParamKey extends MessagePageParamKey<MessageInitShape<I>>,\n  SelectOutData = MessageShape<O>,\n  SelectOutPageParam = unknown,\n>(\n  schema: DescMethodUnary<I, O>,\n  input: MessageInitWithPageParam<MessageInitShape<I>, ParamKey>,\n  {\n    transport,\n    pageParamKey,\n    getNextPageParam,\n    headers,\n    ...queryOptions\n  }: UseSuspenseInfiniteQueryOptions<\n    I,\n    O,\n    ParamKey,\n    SelectOutData,\n    SelectOutPageParam\n  >,\n): UseSuspenseInfiniteQueryResult<\n  InfiniteData<SelectOutData, SelectOutPageParam>,\n  ConnectError\n> {\n  const transportFromCtx = useTransport();\n  const baseOptions = createInfiniteQueryOptions(schema, input, {\n    transport: transport ?? transportFromCtx,\n    getNextPageParam,\n    pageParamKey,\n    headers,\n  });\n  return tsUseSuspenseInfiniteQuery({\n    ...baseOptions,\n    ...queryOptions,\n  });\n}\n"
  },
  {
    "path": "packages/connect-query/src/use-mutation.test.ts",
    "content": "// Copyright 2021-2023 The Connect Authors\n//\n// Licensed under the Apache License, Version 2.0 (the \"License\");\n// you may not use this file except in compliance with the License.\n// You may obtain a copy of the License at\n//\n//      http://www.apache.org/licenses/LICENSE-2.0\n//\n// Unless required by applicable law or agreed to in writing, software\n// distributed under the License is distributed on an \"AS IS\" BASIS,\n// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n// See the License for the specific language governing permissions and\n// limitations under the License.\n\nimport { create } from \"@bufbuild/protobuf\";\nimport { renderHook, waitFor } from \"@testing-library/react\";\nimport { mockPaginatedTransport } from \"test-utils\";\nimport { ListResponseSchema, ListService } from \"test-utils/gen/list_pb.js\";\nimport { describe, expect, it, vi } from \"vitest\";\n\nimport { wrapper } from \"./test/test-wrapper.js\";\nimport { useMutation } from \"./use-mutation.js\";\n\n// TODO: maybe create a helper to take a service and method and generate this.\nconst methodDescriptor = ListService.method.list;\n\nconst mockedPaginatedTransport = mockPaginatedTransport();\n\ndescribe(\"useMutation\", () => {\n  it(\"performs a mutation\", async () => {\n    const onSuccess = vi.fn();\n    const { result } = renderHook(\n      () => {\n        return useMutation(methodDescriptor, {\n          onSuccess,\n        });\n      },\n      wrapper({}, mockedPaginatedTransport),\n    );\n\n    result.current.mutate({\n      page: 0n,\n    });\n\n    await waitFor(() => {\n      expect(result.current.isSuccess).toBeTruthy();\n    });\n\n    expect(onSuccess).toHaveBeenCalledWith(\n      create(ListResponseSchema, {\n        items: [\"-2 Item\", \"-1 Item\", \"0 Item\"],\n        page: 0n,\n      }),\n      {\n        page: 0n,\n      },\n      undefined,\n    );\n  });\n\n  it(\"can be provided a custom transport\", async () => {\n    const { result } = renderHook(\n      () => {\n        return useMutation(methodDescriptor, {\n          transport: mockPaginatedTransport({\n            page: 1n,\n            items: [\"Intercepted!\"],\n          }),\n        });\n      },\n      wrapper({}, mockedPaginatedTransport),\n    );\n\n    result.current.mutate({\n      page: 0n,\n    });\n\n    await waitFor(() => {\n      expect(result.current.isSuccess).toBeTruthy();\n    });\n\n    expect(result.current.data?.items[0]).toBe(\"Intercepted!\");\n  });\n\n  it(\"can forward onMutate params\", async () => {\n    const onSuccess = vi.fn();\n    const { result } = renderHook(\n      () => {\n        return useMutation(methodDescriptor, {\n          onMutate: (variables) => {\n            return {\n              somethingElse: `Some additional context: ${(variables.page ?? 0n) + 2n}`,\n            };\n          },\n          onSuccess: (data, variables, context) => {\n            onSuccess(data, variables, context);\n            // Customizing on success so we can test the types\n            expect(context.somethingElse).toBe(\"Some additional context: 2\");\n          },\n        });\n      },\n      wrapper({}, mockedPaginatedTransport),\n    );\n\n    result.current.mutate({\n      page: 0n,\n    });\n\n    await waitFor(() => {\n      expect(result.current.isSuccess).toBeTruthy();\n    });\n\n    expect(onSuccess).toHaveBeenCalledWith(\n      create(ListResponseSchema, {\n        items: [\"-2 Item\", \"-1 Item\", \"0 Item\"],\n        page: 0n,\n      }),\n      {\n        page: 0n,\n      },\n      { somethingElse: \"Some additional context: 2\" },\n    );\n  });\n});\n"
  },
  {
    "path": "packages/connect-query/src/use-mutation.ts",
    "content": "// Copyright 2021-2023 The Connect Authors\n//\n// Licensed under the Apache License, Version 2.0 (the \"License\");\n// you may not use this file except in compliance with the License.\n// You may obtain a copy of the License at\n//\n//      http://www.apache.org/licenses/LICENSE-2.0\n//\n// Unless required by applicable law or agreed to in writing, software\n// distributed under the License is distributed on an \"AS IS\" BASIS,\n// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n// See the License for the specific language governing permissions and\n// limitations under the License.\n\nimport type {\n  DescMessage,\n  DescMethodUnary,\n  MessageInitShape,\n  MessageShape,\n} from \"@bufbuild/protobuf\";\nimport type { ConnectError, Transport } from \"@connectrpc/connect\";\nimport { callUnaryMethod } from \"@connectrpc/connect-query-core\";\nimport type {\n  UseMutationOptions as TSUseMutationOptions,\n  UseMutationResult,\n} from \"@tanstack/react-query\";\nimport { useMutation as tsUseMutation } from \"@tanstack/react-query\";\nimport { useCallback } from \"react\";\n\nimport { useTransport } from \"./use-transport.js\";\n\n/**\n * Options for useMutation\n */\nexport type UseMutationOptions<\n  I extends DescMessage,\n  O extends DescMessage,\n  Ctx = unknown,\n> = TSUseMutationOptions<\n  MessageShape<O>,\n  ConnectError,\n  MessageInitShape<I>,\n  Ctx\n> & {\n  /** The transport to be used for the fetching. */\n  transport?: Transport;\n};\n\n/**\n * Query the method provided. Maps to useMutation on tanstack/react-query\n */\nexport function useMutation<\n  I extends DescMessage,\n  O extends DescMessage,\n  Ctx = unknown,\n>(\n  schema: DescMethodUnary<I, O>,\n  { transport, ...queryOptions }: UseMutationOptions<I, O, Ctx> = {},\n): UseMutationResult<MessageShape<O>, ConnectError, MessageInitShape<I>, Ctx> {\n  const transportFromCtx = useTransport();\n  const transportToUse = transport ?? transportFromCtx;\n  const mutationFn = useCallback(\n    async (input: MessageInitShape<I>) =>\n      callUnaryMethod(transportToUse, schema, input),\n    [transportToUse, schema],\n  );\n  return tsUseMutation({\n    ...queryOptions,\n    mutationFn,\n  });\n}\n"
  },
  {
    "path": "packages/connect-query/src/use-query.test.ts",
    "content": "// Copyright 2021-2023 The Connect Authors\n//\n// Licensed under the Apache License, Version 2.0 (the \"License\");\n// you may not use this file except in compliance with the License.\n// You may obtain a copy of the License at\n//\n//      http://www.apache.org/licenses/LICENSE-2.0\n//\n// Unless required by applicable law or agreed to in writing, software\n// distributed under the License is distributed on an \"AS IS\" BASIS,\n// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n// See the License for the specific language governing permissions and\n// limitations under the License.\n\nimport { create } from \"@bufbuild/protobuf\";\nimport {\n  createConnectQueryKey,\n  skipToken,\n} from \"@connectrpc/connect-query-core\";\nimport { renderHook, waitFor } from \"@testing-library/react\";\nimport { mockBigInt, mockEliza } from \"test-utils\";\nimport { BigIntService } from \"test-utils/gen/bigint_pb.js\";\nimport { ElizaService } from \"test-utils/gen/eliza_pb.js\";\nimport { describe, expect, it } from \"vitest\";\n\nimport { wrapper } from \"./test/test-wrapper.js\";\nimport { useQuery, useSuspenseQuery } from \"./use-query.js\";\n\n// TODO: maybe create a helper to take a service and method and generate this.\nconst sayMethodDescriptor = ElizaService.method.say;\n\nconst mockedElizaTransport = mockEliza();\n\nconst bigintTransport = mockBigInt();\n\nconst elizaWithDelayTransport = mockEliza(undefined, true);\n\ndescribe(\"useQuery\", () => {\n  it(\"can query data\", async () => {\n    const { result } = renderHook(\n      () => {\n        return useQuery(sayMethodDescriptor, {\n          sentence: \"hello\",\n        });\n      },\n      wrapper({}, mockedElizaTransport),\n    );\n\n    await waitFor(() => {\n      expect(result.current.isSuccess).toBeTruthy();\n    });\n\n    expect(typeof result.current.data?.sentence).toBe(\"string\");\n  });\n\n  it(\"can be disabled\", () => {\n    const { result } = renderHook(\n      () => {\n        return useQuery(sayMethodDescriptor, skipToken);\n      },\n      wrapper(undefined, mockedElizaTransport),\n    );\n    expect(result.current.isPending).toBeTruthy();\n    expect(result.current.isFetching).toBeFalsy();\n  });\n\n  it(\"can be provided a custom transport\", async () => {\n    const transport = mockEliza({\n      sentence: \"Intercepted!\",\n    });\n    const { result } = renderHook(\n      () => {\n        return useQuery(\n          sayMethodDescriptor,\n          {},\n          {\n            transport,\n          },\n        );\n      },\n      wrapper(undefined, mockedElizaTransport),\n    );\n    await waitFor(() => {\n      expect(result.current.isSuccess).toBeTruthy();\n    });\n\n    expect(result.current.data?.sentence).toBe(\"Intercepted!\");\n  });\n\n  it(\"can be provided other props for react-query\", () => {\n    const { result } = renderHook(\n      () => {\n        return useQuery(\n          sayMethodDescriptor,\n          {},\n          {\n            transport: elizaWithDelayTransport,\n            placeholderData: create(sayMethodDescriptor.output, {\n              sentence: \"placeholder!\",\n            }),\n          },\n        );\n      },\n      wrapper(undefined, mockedElizaTransport),\n    );\n    expect(result.current.data?.sentence).toBe(\"placeholder!\");\n  });\n\n  it(\"can be used along with the select\", async () => {\n    const { result } = renderHook(\n      () => {\n        return useQuery(\n          sayMethodDescriptor,\n          {},\n          {\n            select: (data) => data.sentence.length,\n          },\n        );\n      },\n      wrapper(undefined, mockedElizaTransport),\n    );\n\n    await waitFor(() => {\n      expect(result.current.isSuccess).toBeTruthy();\n    });\n\n    expect(result.current.data).toBe(6);\n  });\n\n  it(\"can be disabled with enabled: false\", () => {\n    const { result } = renderHook(\n      () => {\n        return useQuery(\n          sayMethodDescriptor,\n          {\n            sentence: \"hello\",\n          },\n          {\n            enabled: false,\n          },\n        );\n      },\n      wrapper({}, mockedElizaTransport),\n    );\n\n    expect(result.current.data).toBeUndefined();\n    expect(result.current.isPending).toBeTruthy();\n    expect(result.current.isFetching).toBeFalsy();\n  });\n\n  it(\"can be disabled with enabled: false in QueryClient default options\", () => {\n    const { result } = renderHook(\n      () => {\n        return useQuery(sayMethodDescriptor, {\n          sentence: \"hello\",\n        });\n      },\n      wrapper(\n        {\n          defaultOptions: {\n            queries: {\n              enabled: false,\n            },\n          },\n        },\n        mockedElizaTransport,\n      ),\n    );\n\n    expect(result.current.data).toBeUndefined();\n    expect(result.current.isPending).toBeTruthy();\n    expect(result.current.isFetching).toBeFalsy();\n  });\n\n  it(\"can be disabled with skipToken\", () => {\n    const { result } = renderHook(\n      () => {\n        return useQuery(sayMethodDescriptor, skipToken);\n      },\n      wrapper({}, mockedElizaTransport),\n    );\n\n    expect(result.current.data).toBeUndefined();\n    expect(result.current.isPending).toBeTruthy();\n    expect(result.current.isFetching).toBeFalsy();\n  });\n\n  it(\"supports schemas with bigint keys\", async () => {\n    const { result } = renderHook(\n      () => {\n        return useQuery(BigIntService.method.count, {\n          add: 2n,\n        });\n      },\n      wrapper({}, bigintTransport),\n    );\n\n    await waitFor(() => {\n      expect(result.current.isSuccess).toBeTruthy();\n    });\n\n    expect(result.current.data?.count).toBe(1n);\n  });\n\n  it(\"data can be fetched from cache\", async () => {\n    const { queryClient, ...rest } = wrapper({}, bigintTransport);\n    const { result } = renderHook(() => {\n      return useQuery(BigIntService.method.count, {});\n    }, rest);\n\n    await waitFor(() => {\n      expect(result.current.isSuccess).toBeTruthy();\n    });\n\n    expect(\n      queryClient.getQueryData(\n        createConnectQueryKey({\n          schema: BigIntService.method.count,\n          input: {},\n          transport: bigintTransport,\n          cardinality: \"finite\",\n        }),\n      ),\n    ).toBe(result.current.data);\n  });\n});\n\ndescribe(\"useSuspenseQuery\", () => {\n  it(\"can query data\", async () => {\n    const { result } = renderHook(\n      () => {\n        return useSuspenseQuery(sayMethodDescriptor, {\n          sentence: \"hello\",\n        });\n      },\n      wrapper({}, mockedElizaTransport),\n    );\n\n    await waitFor(() => {\n      expect(result.current.isSuccess).toBeTruthy();\n    });\n\n    expect(typeof result.current.data.sentence).toBe(\"string\");\n  });\n\n  it(\"can be used along with the select\", async () => {\n    const { result } = renderHook(\n      () => {\n        return useSuspenseQuery(\n          sayMethodDescriptor,\n          {\n            sentence: \"hello\",\n          },\n          {\n            select: (data) => data.sentence.length,\n          },\n        );\n      },\n      wrapper({}, mockedElizaTransport),\n    );\n\n    await waitFor(() => {\n      expect(result.current.isSuccess).toBeTruthy();\n    });\n\n    expect(result.current.data).toBe(11);\n  });\n\n  it(\"can pass headers through\", async () => {\n    let resolve: () => void;\n    const promise = new Promise<void>((res) => {\n      resolve = res;\n    });\n    const transport = mockEliza(\n      {\n        sentence: \"Response 1\",\n      },\n      false,\n      {\n        router: {\n          interceptors: [\n            (next) => (req) => {\n              expect(req.header.get(\"x-custom-header\")).toEqual(\"custom-value\");\n              resolve();\n              return next(req);\n            },\n          ],\n        },\n      },\n    );\n    const { result } = renderHook(\n      () => {\n        return useSuspenseQuery(\n          sayMethodDescriptor,\n          {\n            sentence: \"hello\",\n          },\n          {\n            transport,\n            headers: {\n              \"x-custom-header\": \"custom-value\",\n            },\n          },\n        );\n      },\n      wrapper({}, mockedElizaTransport),\n    );\n\n    await waitFor(() => {\n      expect(result.current.isSuccess).toBeTruthy();\n    });\n\n    await promise;\n\n    expect(result.current.data.sentence).toBe(\"Response 1\");\n  });\n});\n"
  },
  {
    "path": "packages/connect-query/src/use-query.ts",
    "content": "// Copyright 2021-2023 The Connect Authors\n//\n// Licensed under the Apache License, Version 2.0 (the \"License\");\n// you may not use this file except in compliance with the License.\n// You may obtain a copy of the License at\n//\n//      http://www.apache.org/licenses/LICENSE-2.0\n//\n// Unless required by applicable law or agreed to in writing, software\n// distributed under the License is distributed on an \"AS IS\" BASIS,\n// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n// See the License for the specific language governing permissions and\n// limitations under the License.\n\nimport type {\n  DescMessage,\n  DescMethodUnary,\n  MessageInitShape,\n  MessageShape,\n} from \"@bufbuild/protobuf\";\nimport type { ConnectError, Transport } from \"@connectrpc/connect\";\nimport type {\n  ConnectQueryKey,\n  SkipToken,\n} from \"@connectrpc/connect-query-core\";\nimport { createQueryOptions } from \"@connectrpc/connect-query-core\";\nimport type {\n  UseQueryOptions as TanStackUseQueryOptions,\n  UseQueryResult,\n  UseSuspenseQueryOptions as TanStackUseSuspenseQueryOptions,\n  UseSuspenseQueryResult,\n} from \"@tanstack/react-query\";\nimport {\n  useQuery as tsUseQuery,\n  useSuspenseQuery as tsUseSuspenseQuery,\n} from \"@tanstack/react-query\";\n\nimport { useTransport } from \"./use-transport.js\";\n\n/**\n * Options for useQuery\n */\nexport type UseQueryOptions<\n  O extends DescMessage,\n  SelectOutData = MessageShape<O>,\n> = Omit<\n  TanStackUseQueryOptions<\n    MessageShape<O>,\n    ConnectError,\n    SelectOutData,\n    ConnectQueryKey<O>\n  >,\n  \"queryFn\" | \"queryKey\"\n> & {\n  /** The transport to be used for the fetching. */\n  transport?: Transport;\n};\n\n/**\n * Query the method provided. Maps to useQuery on tanstack/react-query\n */\nexport function useQuery<\n  I extends DescMessage,\n  O extends DescMessage,\n  SelectOutData = MessageShape<O>,\n>(\n  schema: DescMethodUnary<I, O>,\n  input?: SkipToken | MessageInitShape<I>,\n  { transport, ...queryOptions }: UseQueryOptions<O, SelectOutData> = {},\n): UseQueryResult<SelectOutData, ConnectError> {\n  const transportFromCtx = useTransport();\n  const baseOptions = createQueryOptions(schema, input, {\n    transport: transport ?? transportFromCtx,\n  });\n  return tsUseQuery({\n    ...baseOptions,\n    ...queryOptions,\n  });\n}\n\n/**\n * Options for useSuspenseQuery\n */\nexport type UseSuspenseQueryOptions<\n  O extends DescMessage,\n  SelectOutData = 0,\n> = Omit<\n  TanStackUseSuspenseQueryOptions<\n    MessageShape<O>,\n    ConnectError,\n    SelectOutData,\n    ConnectQueryKey<O>\n  >,\n  \"queryFn\" | \"queryKey\"\n> & {\n  /** The transport to be used for the fetching. */\n  transport?: Transport;\n  headers?: HeadersInit;\n};\n\n/**\n * Query the method provided. Maps to useSuspenseQuery on tanstack/react-query\n */\nexport function useSuspenseQuery<\n  I extends DescMessage,\n  O extends DescMessage,\n  SelectOutData = MessageShape<O>,\n>(\n  schema: DescMethodUnary<I, O>,\n  input?: MessageInitShape<I>,\n  {\n    transport,\n    headers,\n    ...queryOptions\n  }: UseSuspenseQueryOptions<O, SelectOutData> = {},\n): UseSuspenseQueryResult<SelectOutData, ConnectError> {\n  const transportFromCtx = useTransport();\n  const baseOptions = createQueryOptions(schema, input, {\n    transport: transport ?? transportFromCtx,\n    headers,\n  });\n  return tsUseSuspenseQuery({\n    ...baseOptions,\n    ...queryOptions,\n  });\n}\n"
  },
  {
    "path": "packages/connect-query/src/use-transport.test.tsx",
    "content": "// Copyright 2021-2023 The Connect Authors\n//\n// Licensed under the Apache License, Version 2.0 (the \"License\");\n// you may not use this file except in compliance with the License.\n// You may obtain a copy of the License at\n//\n//      http://www.apache.org/licenses/LICENSE-2.0\n//\n// Unless required by applicable law or agreed to in writing, software\n// distributed under the License is distributed on an \"AS IS\" BASIS,\n// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n// See the License for the specific language governing permissions and\n// limitations under the License.\n\nimport { ConnectError } from \"@connectrpc/connect\";\nimport { renderHook, waitFor } from \"@testing-library/react\";\nimport { mockBigInt } from \"test-utils\";\nimport { ElizaService } from \"test-utils/gen/eliza_pb.js\";\nimport { describe, expect, it } from \"vitest\";\n\nimport { wrapper } from \"./test/test-wrapper.js\";\nimport { useQuery } from \"./use-query.js\";\nimport { TransportProvider, useTransport } from \"./use-transport.js\";\n\nconst sayMethodDescriptor = ElizaService.method.say;\n\nconst error = new ConnectError(\n  \"To use Connect, you must provide a `Transport`: a simple object that handles `unary` and `stream` requests. `Transport` objects can easily be created by using `@connectrpc/connect-web`'s exports `createConnectTransport` and `createGrpcWebTransport`. see: https://connectrpc.com/docs/web/getting-started for more info.\",\n);\n\ndescribe(\"useTransport\", () => {\n  it(\"throws the fallback error\", async () => {\n    const { result, rerender } = renderHook(\n      () => useQuery(sayMethodDescriptor, undefined, { retry: false }),\n      {\n        wrapper: wrapper().queryClientWrapper,\n      },\n    );\n    rerender();\n\n    expect(result.current.error).toStrictEqual(null);\n    expect(result.current.isError).toStrictEqual(false);\n\n    await waitFor(() => {\n      expect(result.current.isError).toStrictEqual(true);\n    });\n\n    expect(result.current.error).toEqual(error);\n  });\n});\n\ndescribe(\"TransportProvider\", () => {\n  it(\"provides a custom transport to the useTransport hook\", () => {\n    const transport = mockBigInt();\n    const { result } = renderHook(() => useTransport(), {\n      wrapper: ({ children }) => (\n        <TransportProvider transport={transport}>{children}</TransportProvider>\n      ),\n    });\n    expect(result.current).toBe(transport);\n  });\n});\n"
  },
  {
    "path": "packages/connect-query/src/use-transport.tsx",
    "content": "// Copyright 2021-2023 The Connect Authors\n//\n// Licensed under the Apache License, Version 2.0 (the \"License\");\n// you may not use this file except in compliance with the License.\n// You may obtain a copy of the License at\n//\n//      http://www.apache.org/licenses/LICENSE-2.0\n//\n// Unless required by applicable law or agreed to in writing, software\n// distributed under the License is distributed on an \"AS IS\" BASIS,\n// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n// See the License for the specific language governing permissions and\n// limitations under the License.\n\nimport type { Transport } from \"@connectrpc/connect\";\nimport { ConnectError } from \"@connectrpc/connect\";\nimport type { FC, PropsWithChildren } from \"react\";\nimport { createContext, useContext } from \"react\";\n\nconst fallbackTransportError = new ConnectError(\n  \"To use Connect, you must provide a `Transport`: a simple object that handles `unary` and `stream` requests. `Transport` objects can easily be created by using `@connectrpc/connect-web`'s exports `createConnectTransport` and `createGrpcWebTransport`. see: https://connectrpc.com/docs/web/getting-started for more info.\",\n);\n\n// istanbul ignore next\nexport const fallbackTransport: Transport = {\n  unary: () => {\n    throw fallbackTransportError;\n  },\n  stream: () => {\n    throw fallbackTransportError;\n  },\n};\n\nconst transportContext = createContext(fallbackTransport);\n\n/**\n * Use this helper to get the default transport that's currently attached to the React context for the calling component.\n */\nexport const useTransport = () => useContext(transportContext);\n\n/**\n * `TransportProvider` is the main mechanism by which Connect-Query keeps track of the `Transport` used by your application.\n *\n * Broadly speaking, \"transport\" joins two concepts:\n *\n *   1. The protocol of communication.  For this there are two options: the {@link https://connectrpc.com/docs/protocol/ Connect Protocol}, or the {@link https://github.com/grpc/grpc/blob/master/doc/PROTOCOL-WEB.md gRPC-Web Protocol}.\n *   1. The protocol options.  The primary important piece of information here is the `baseUrl`, but there are also other potentially critical options like request credentials and binary wire format encoding options.\n *\n * With these two pieces of information in hand, the transport provides the critical mechanism by which your app can make network requests.\n *\n * To learn more about the two modes of transport, take a look at the npm package `@connectrpc/connect-web`.\n *\n * To get started with Connect-Query, simply import a transport (either `createConnectTransport` or `createGrpcWebTransport` from `@connectrpc/connect-web`) and pass it to the provider.\n *\n * @example\n * import { QueryClient, QueryClientProvider } from \"@tanstack/react-query\";\n * import { TransportProvider } from \"@connectrpc/connect-query\";\n *\n * const queryClient = new QueryClient();\n *\n * export const App() {\n *   const transport = createConnectTransport({\n *     baseUrl: \"<your baseUrl here>\",\n *   });\n *   return (\n *     <TransportProvider transport={transport}>\n *       <QueryClientProvider client={queryClient}>\n *          <YourApp />\n *       </QueryClientProvider>\n *     </TransportProvider>\n *   );\n * }\n */\nexport const TransportProvider: FC<\n  PropsWithChildren<{\n    transport: Transport;\n  }>\n> = ({ children, transport }) => (\n  <transportContext.Provider value={transport}>\n    {children}\n  </transportContext.Provider>\n);\n"
  },
  {
    "path": "packages/connect-query/tsconfig.build.json",
    "content": "{\n  \"extends\": \"../../tsconfig.base.json\",\n  \"files\": [\"src/index.ts\"],\n  \"compilerOptions\": {\n    \"jsx\": \"react-jsx\"\n  }\n}\n"
  },
  {
    "path": "packages/connect-query/tsconfig.json",
    "content": "{\n  \"include\": [\n    \"**/*.test.ts\",\n    \"**/*.test.tsx\",\n    \"src/test/**.tsx\",\n    \"vite.config.ts\"\n  ],\n  \"extends\": \"./tsconfig.build.json\"\n}\n"
  },
  {
    "path": "packages/connect-query/vite.config.ts",
    "content": "// Copyright 2021-2023 The Connect Authors\n//\n// Licensed under the Apache License, Version 2.0 (the \"License\");\n// you may not use this file except in compliance with the License.\n// You may obtain a copy of the License at\n//\n//      http://www.apache.org/licenses/LICENSE-2.0\n//\n// Unless required by applicable law or agreed to in writing, software\n// distributed under the License is distributed on an \"AS IS\" BASIS,\n// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n// See the License for the specific language governing permissions and\n// limitations under the License.\n\nimport { defineConfig } from \"vitest/config\";\n\n// https://vitejs.dev/config/\nexport default defineConfig({\n  test: {\n    environment: \"jsdom\",\n    typecheck: {\n      enabled: true,\n      // Modified to typecheck definition files as well as source files\n      include: [\"**/*.{test,spec}?(-d).?(c|m)[jt]s?(x)\"],\n    },\n    coverage: {\n      provider: \"istanbul\",\n      thresholds: {\n        branches: 100,\n        functions: 100,\n        lines: 100,\n        statements: 100,\n      },\n    },\n  },\n});\n"
  },
  {
    "path": "packages/connect-query-core/README.md",
    "content": "# @connectrpc/connect-query-core\n\nThis package provides the core functionality for the Connect-Query API. It exposes all the necessary functions to use with the different variants of the tanstack/query packages. Documentation for these APIs can be found in the main repo readme at https://github.com/connectrpc/connect-query-es and covers any non-hook functions (anything that doesn't start with `use`).\n"
  },
  {
    "path": "packages/connect-query-core/package.json",
    "content": "{\n  \"name\": \"@connectrpc/connect-query-core\",\n  \"version\": \"2.2.0\",\n  \"description\": \"Core of Connect-Query, framework agnostic helpers for type-safe queries.\",\n  \"license\": \"Apache-2.0\",\n  \"repository\": {\n    \"type\": \"git\",\n    \"url\": \"https://github.com/connectrpc/connect-query-es.git\",\n    \"directory\": \"packages/connect-query-core\"\n  },\n  \"scripts\": {\n    \"prebuild\": \"rm -rf ./dist/*\",\n    \"build\": \"npm run build:cjs && npm run build:esm\",\n    \"build:cjs\": \"tsc --project tsconfig.build.json --module commonjs --verbatimModuleSyntax false --moduleResolution node10 --outDir ./dist/cjs --declaration --declarationDir ./dist/cjs && echo >./dist/cjs/package.json '{\\\"type\\\":\\\"commonjs\\\"}'\",\n    \"build:esm\": \"tsc --project tsconfig.build.json --outDir ./dist/esm --declaration --declarationDir ./dist/esm\",\n    \"test\": \"vitest --run\",\n    \"test:watch\": \"vitest --watch\",\n    \"format\": \"prettier --write --ignore-unknown '.' '!dist'\",\n    \"license-header\": \"license-header\",\n    \"lint\": \"eslint --max-warnings 0 .\",\n    \"attw\": \"attw --pack\"\n  },\n  \"type\": \"module\",\n  \"sideEffects\": false,\n  \"main\": \"./dist/cjs/index.js\",\n  \"exports\": {\n    \".\": {\n      \"import\": \"./dist/esm/index.js\",\n      \"require\": \"./dist/cjs/index.js\"\n    }\n  },\n  \"devDependencies\": {\n    \"@arethetypeswrong/cli\": \"^0.18.1\",\n    \"@bufbuild/buf\": \"1.54.0\",\n    \"@bufbuild/jest-environment-jsdom\": \"^0.1.1\",\n    \"@bufbuild/protobuf\": \"^2.5.1\",\n    \"@bufbuild/protoc-gen-es\": \"^2.5.1\",\n    \"@connectrpc/connect\": \"^2.0.2\",\n    \"@connectrpc/connect-web\": \"^2.0.2\",\n    \"test-utils\": \"*\",\n    \"typescript\": \"^5.8.3\",\n    \"@tanstack/query-core\": \"^5.79.0\"\n  },\n  \"peerDependencies\": {\n    \"@bufbuild/protobuf\": \"2.x\",\n    \"@connectrpc/connect\": \"^2.0.1\",\n    \"@tanstack/query-core\": \">=5.62.0\"\n  },\n  \"files\": [\n    \"dist/**\"\n  ]\n}\n"
  },
  {
    "path": "packages/connect-query-core/src/call-unary-method.ts",
    "content": "// Copyright 2021-2023 The Connect Authors\n//\n// Licensed under the Apache License, Version 2.0 (the \"License\");\n// you may not use this file except in compliance with the License.\n// You may obtain a copy of the License at\n//\n//      http://www.apache.org/licenses/LICENSE-2.0\n//\n// Unless required by applicable law or agreed to in writing, software\n// distributed under the License is distributed on an \"AS IS\" BASIS,\n// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n// See the License for the specific language governing permissions and\n// limitations under the License.\n\nimport type {\n  DescMessage,\n  DescMethodUnary,\n  MessageInitShape,\n  MessageShape,\n} from \"@bufbuild/protobuf\";\nimport { create } from \"@bufbuild/protobuf\";\nimport type { Transport } from \"@connectrpc/connect\";\n\n/**\n * Call a unary method given its signature and input.\n */\n// eslint-disable-next-line @typescript-eslint/max-params -- 4th param is optional\nexport async function callUnaryMethod<\n  I extends DescMessage,\n  O extends DescMessage,\n>(\n  transport: Transport,\n  schema: DescMethodUnary<I, O>,\n  input: MessageInitShape<I> | undefined,\n  options?: {\n    signal?: AbortSignal;\n    headers?: HeadersInit;\n  },\n): Promise<MessageShape<O>> {\n  const result = await transport.unary(\n    schema,\n    options?.signal,\n    undefined,\n    options?.headers,\n    input ?? create(schema.input),\n    undefined,\n  );\n  return result.message;\n}\n"
  },
  {
    "path": "packages/connect-query-core/src/connect-query-key.test.ts",
    "content": "// Copyright 2021-2023 The Connect Authors\n//\n// Licensed under the Apache License, Version 2.0 (the \"License\");\n// you may not use this file except in compliance with the License.\n// You may obtain a copy of the License at\n//\n//      http://www.apache.org/licenses/LICENSE-2.0\n//\n// Unless required by applicable law or agreed to in writing, software\n// distributed under the License is distributed on an \"AS IS\" BASIS,\n// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n// See the License for the specific language governing permissions and\n// limitations under the License.\n\nimport { create } from \"@bufbuild/protobuf\";\nimport type { MessageInitShape } from \"@bufbuild/protobuf\";\nimport type { Transport } from \"@connectrpc/connect\";\nimport {\n  ElizaService,\n  SayRequestSchema,\n  SayResponseSchema,\n  type SayResponse,\n} from \"test-utils/gen/eliza_pb.js\";\nimport {\n  NestedListRequestSchema,\n  ListRequestSchema,\n  ListResponseSchema,\n  ListService,\n  type ListResponse,\n} from \"test-utils/gen/list_pb.js\";\nimport { describe, expect, expectTypeOf, it } from \"vitest\";\n\nimport { createConnectQueryKey } from \"./connect-query-key.js\";\nimport { skipToken } from \"./index.js\";\nimport type { MessagePageParamKey } from \"./index.js\";\nimport { createMessageKey } from \"./message-key.js\";\nimport { createTransportKey } from \"./transport-key.js\";\nimport { type InfiniteData, QueryClient } from \"@tanstack/query-core\";\n\ndescribe(\"createConnectQueryKey\", () => {\n  const fakeTransport: Transport = {\n    async stream() {\n      return Promise.reject(new Error(\"unexpected\"));\n    },\n    async unary() {\n      return Promise.reject(new Error(\"unexpected\"));\n    },\n  };\n\n  it(\"creates a full key\", () => {\n    const key = createConnectQueryKey({\n      transport: fakeTransport,\n      schema: ElizaService.method.say,\n      input: create(SayRequestSchema, { sentence: \"hi\" }),\n      cardinality: \"finite\",\n    });\n    expect(key).toStrictEqual([\n      \"connect-query\",\n      {\n        transport: createTransportKey(fakeTransport),\n        serviceName: \"connectrpc.eliza.v1.ElizaService\",\n        methodName: \"Say\",\n        cardinality: \"finite\",\n        input: createMessageKey(SayRequestSchema, { sentence: \"hi\" }),\n      },\n    ]);\n  });\n\n  it(\"creates a full infinite key\", () => {\n    const key = createConnectQueryKey({\n      transport: fakeTransport,\n      schema: ListService.method.list,\n      input: create(ListRequestSchema, { page: 0n }),\n      pageParamKey: \"page\",\n      cardinality: \"infinite\",\n    });\n    expect(key).toStrictEqual([\n      \"connect-query\",\n      {\n        transport: createTransportKey(fakeTransport),\n        serviceName: \"ListService\",\n        methodName: \"List\",\n        cardinality: \"infinite\",\n        input: createMessageKey(ListRequestSchema, {}),\n      },\n    ]);\n  });\n\n  it(\"creates a full infinite key with nested pageParamKey\", () => {\n    const key = createConnectQueryKey({\n      transport: fakeTransport,\n      schema: ListService.method.nestedList,\n      input: create(NestedListRequestSchema, { nested: { page: 0n } }),\n      pageParamKey: \"nested.page\",\n      cardinality: \"infinite\",\n    });\n    expect(key).toStrictEqual([\n      \"connect-query\",\n      {\n        transport: createTransportKey(fakeTransport),\n        serviceName: \"ListService\",\n        methodName: \"NestedList\",\n        cardinality: \"infinite\",\n        input: createMessageKey(NestedListRequestSchema, { nested: {} }),\n      },\n    ]);\n  });\n\n  it(\"rejects an invalid nested pageParamKey segment\", () => {\n    type Key = MessagePageParamKey<\n      MessageInitShape<typeof NestedListRequestSchema>\n    >;\n    // @ts-expect-error(2322) nested segment must be a valid key\n    const invalidPageParamKey: Key = \"nested.p@ge\";\n    expect(invalidPageParamKey).toBeDefined();\n  });\n\n  it(\"rejects array prototype key paths\", () => {\n    type Key = MessagePageParamKey<{\n      nested: {\n        page: bigint;\n      };\n      items: string[];\n    }>;\n    // @ts-expect-error(2322) array prototype keys are not valid path segments\n    const invalidArrayPrototypePath: Key = \"items.pop\";\n    expect(invalidArrayPrototypePath).toBeDefined();\n  });\n\n  it(\"rejects protobuf internal keys\", () => {\n    type Key = MessagePageParamKey<MessageInitShape<typeof SayRequestSchema>>;\n    // @ts-expect-error(2322) protobuf internal key is not supported\n    const invalidTypeNameKey: Key = \"$typeName\";\n    // @ts-expect-error(2322) protobuf internal key is not supported\n    const invalidUnknownKey: Key = \"$unknown\";\n    expect(invalidTypeNameKey).toBeDefined();\n    expect(invalidUnknownKey).toBeDefined();\n  });\n\n  it(\"allows input: undefined\", () => {\n    const key = createConnectQueryKey({\n      schema: ElizaService.method.say,\n      input: undefined,\n      cardinality: \"finite\",\n    });\n    expect(key[1].input).toBeUndefined();\n  });\n\n  it(\"allows to omit input\", () => {\n    const key = createConnectQueryKey({\n      schema: ElizaService.method.say,\n      cardinality: \"finite\",\n    });\n    expect(key[1].input).toBeUndefined();\n  });\n\n  it(\"allows input: skipToken\", () => {\n    const key = createConnectQueryKey({\n      schema: ElizaService.method.say,\n      input: skipToken,\n      cardinality: \"finite\",\n    });\n    expect(key[1].input).toBe(\"skipped\");\n  });\n\n  it(\"allows to set cardinality: finite\", () => {\n    const key = createConnectQueryKey({\n      schema: ElizaService.method.say,\n      cardinality: \"finite\",\n    });\n    expect(key[1].cardinality).toBe(\"finite\");\n  });\n\n  it(\"allows to set cardinality: undefined\", () => {\n    const key = createConnectQueryKey({\n      schema: ElizaService.method.say,\n      cardinality: undefined,\n    });\n    expect(key[1].cardinality).toBeUndefined();\n  });\n\n  it(\"allows to set a service schema\", () => {\n    const key = createConnectQueryKey({\n      schema: ElizaService,\n      cardinality: \"finite\",\n    });\n    expect(key[1].serviceName).toBe(ElizaService.typeName);\n    expect(key[1].methodName).toBeUndefined();\n  });\n\n  it(\"cannot except invalid input\", () => {\n    createConnectQueryKey({\n      // @ts-expect-error(2322) cannot create a key with invalid input\n      schema: ElizaService.method.say,\n      input: {\n        sentence: 1,\n      },\n      cardinality: undefined,\n    });\n  });\n\n  it(\"contains type hints to indicate the output type\", () => {\n    const sampleQueryClient = new QueryClient();\n    const key = createConnectQueryKey({\n      schema: ElizaService.method.say,\n      input: create(SayRequestSchema, { sentence: \"hi\" }),\n      cardinality: \"finite\",\n    });\n    const data = sampleQueryClient.getQueryData(key);\n\n    expectTypeOf(data).toEqualTypeOf<SayResponse | undefined>();\n  });\n\n  it(\"supports typesafe data updaters\", () => {\n    const sampleQueryClient = new QueryClient();\n    const key = createConnectQueryKey({\n      schema: ElizaService.method.say,\n      input: create(SayRequestSchema, { sentence: \"hi\" }),\n      cardinality: \"finite\",\n    });\n    // @ts-expect-error(2345) this is a test to check if the type is correct\n    sampleQueryClient.setQueryData(key, { sentence: 1 });\n    // @ts-expect-error(2345) $typename is required\n    sampleQueryClient.setQueryData(key, {\n      sentence: \"a proper value but missing $typename\",\n    });\n    sampleQueryClient.setQueryData(\n      key,\n      create(SayResponseSchema, { sentence: \"a proper value\" }),\n    );\n\n    sampleQueryClient.setQueryData(key, (prev) => {\n      expectTypeOf(prev).toEqualTypeOf<SayResponse | undefined>();\n      return create(SayResponseSchema, {\n        sentence: \"a proper value\",\n      });\n    });\n  });\n\n  describe(\"headers\", () => {\n    it(\"allows headers to be passed as an object\", () => {\n      const key = createConnectQueryKey({\n        schema: ElizaService.method.say,\n        input: create(SayRequestSchema, { sentence: \"hi\" }),\n        cardinality: \"finite\",\n        headers: {\n          \"x-custom-header\": \"custom-value\",\n        },\n      });\n      expect(key[1].headers).toEqual({\n        \"x-custom-header\": \"custom-value\",\n      });\n    });\n    it(\"allows headers to be passed as a tuple\", () => {\n      const key = createConnectQueryKey({\n        schema: ElizaService.method.say,\n        input: create(SayRequestSchema, { sentence: \"hi\" }),\n        cardinality: \"finite\",\n        headers: [[\"x-custom-header\", \"custom-value\"]],\n      });\n      expect(key[1].headers).toEqual({\n        \"x-custom-header\": \"custom-value\",\n      });\n    });\n    it(\"allows headers to be passed as a HeadersInit\", () => {\n      const key = createConnectQueryKey({\n        schema: ElizaService.method.say,\n        input: create(SayRequestSchema, { sentence: \"hi\" }),\n        cardinality: \"finite\",\n        headers: new Headers({\n          \"x-custom-header\": \"custom-value\",\n        }),\n      });\n      expect(key[1].headers).toEqual({\n        \"x-custom-header\": \"custom-value\",\n      });\n    });\n    it(\"normalizes header values\", () => {\n      const keyA = createConnectQueryKey({\n        schema: ElizaService.method.say,\n        input: create(SayRequestSchema, { sentence: \"hi\" }),\n        cardinality: \"finite\",\n        headers: {\n          foo: \"a\",\n          Foo: \"b\",\n        },\n      });\n      const keyB = createConnectQueryKey({\n        schema: ElizaService.method.say,\n        input: create(SayRequestSchema, { sentence: \"hi\" }),\n        cardinality: \"finite\",\n        headers: {\n          foo: \"a, b\",\n        },\n      });\n      const keyC = createConnectQueryKey({\n        schema: ElizaService.method.say,\n        input: create(SayRequestSchema, { sentence: \"hi\" }),\n        cardinality: \"finite\",\n        headers: [\n          [\"foo\", \"a\"],\n          [\"foo\", \"b\"],\n        ],\n      });\n\n      expect(keyA[1].headers).toEqual(keyB[1].headers);\n      expect(keyA[1].headers).toEqual(keyC[1].headers);\n    });\n  });\n\n  describe(\"infinite queries\", () => {\n    it(\"contains type hints to indicate the output type\", () => {\n      const sampleQueryClient = new QueryClient();\n      const key = createConnectQueryKey({\n        schema: ListService.method.list,\n        input: create(ListRequestSchema, { page: 0n }),\n        cardinality: \"infinite\",\n        pageParamKey: \"page\",\n      });\n      const data = sampleQueryClient.getQueryData(key);\n\n      expectTypeOf(data).toEqualTypeOf<\n        InfiniteData<ListResponse> | undefined\n      >();\n    });\n\n    it(\"supports typesafe data updaters\", () => {\n      const sampleQueryClient = new QueryClient();\n      const key = createConnectQueryKey({\n        schema: ListService.method.list,\n        input: create(ListRequestSchema, { page: 0n }),\n        cardinality: \"infinite\",\n        pageParamKey: \"page\",\n      });\n      sampleQueryClient.setQueryData(key, {\n        pages: [\n          // @ts-expect-error(2345) make sure the shape is as expected\n          { sentence: 1 },\n        ],\n      });\n      sampleQueryClient.setQueryData(key, {\n        // @ts-expect-error(2345) $typename is required\n        pages: [{ sentence: \"a proper value but missing $typename\" }],\n      });\n      sampleQueryClient.setQueryData(key, {\n        pageParams: [0],\n        pages: [create(ListResponseSchema, { items: [\"a proper value\"] })],\n      });\n      sampleQueryClient.setQueryData(key, (prev) => {\n        expectTypeOf(prev).toEqualTypeOf<\n          InfiniteData<ListResponse> | undefined\n        >();\n        return {\n          pageParams: [0],\n          pages: [create(ListResponseSchema, { items: [\"a proper value\"] })],\n        };\n      });\n    });\n  });\n});\n"
  },
  {
    "path": "packages/connect-query-core/src/connect-query-key.ts",
    "content": "// Copyright 2021-2023 The Connect Authors\n//\n// Licensed under the Apache License, Version 2.0 (the \"License\");\n// you may not use this file except in compliance with the License.\n// You may obtain a copy of the License at\n//\n//      http://www.apache.org/licenses/LICENSE-2.0\n//\n// Unless required by applicable law or agreed to in writing, software\n// distributed under the License is distributed on an \"AS IS\" BASIS,\n// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n// See the License for the specific language governing permissions and\n// limitations under the License.\n\nimport type {\n  DescMessage,\n  DescMethod,\n  DescMethodUnary,\n  DescService,\n  MessageInitShape,\n  MessageShape,\n} from \"@bufbuild/protobuf\";\nimport type { ConnectError, Transport } from \"@connectrpc/connect\";\nimport type { DataTag, InfiniteData, SkipToken } from \"@tanstack/query-core\";\n\nimport { createMessageKey } from \"./message-key.js\";\nimport type { MessagePageParamKey } from \"./page-param-key.js\";\nimport { createTransportKey } from \"./transport-key.js\";\n\ntype SharedConnectQueryOptions = {\n  /**\n   * A key for a Transport reference, created with createTransportKey().\n   */\n  transport?: string;\n  /**\n   * The name of the service, e.g. connectrpc.eliza.v1.ElizaService\n   */\n  serviceName: string;\n  /**\n   * The name of the method, e.g. Say.\n   */\n  methodName?: string;\n  /**\n   * A key for the request message, created with createMessageKey(),\n   * or \"skipped\".\n   */\n  input?: Record<string, unknown> | \"skipped\";\n  /**\n   * Headers to be sent with the request.\n   * Note that invalid HTTP header names will raise a TypeError, and that the Set-Cookie header is not supported.\n   */\n  headers?: Record<string, string>;\n};\n\ntype InfiniteConnectQueryKey<OutputMessage extends DescMessage = DescMessage> =\n  DataTag<\n    [\n      \"connect-query\",\n      SharedConnectQueryOptions & {\n        /** This data represents a infinite, paged result */\n        cardinality: \"infinite\";\n      },\n    ],\n    InfiniteData<MessageShape<OutputMessage>>,\n    ConnectError\n  >;\n\ntype FiniteConnectQueryKey<OutputMessage extends DescMessage = DescMessage> =\n  DataTag<\n    [\n      \"connect-query\",\n      SharedConnectQueryOptions & {\n        /** This data represents a finite result */\n        cardinality: \"finite\";\n      },\n    ],\n    MessageShape<OutputMessage>,\n    ConnectError\n  >;\n\n/**\n * TanStack Query manages query caching for you based on query keys. `QueryKey`s in TanStack Query are arrays with arbitrary JSON-serializable data - typically handwritten for each endpoint.\n *\n * In Connect Query, query keys are more structured, since queries are always tied to a service, RPC, input message, and transport. For example, for a query key might look like this:\n *\n * @example\n * [\n *   \"connect-query\",\n *   {\n *     transport: \"t1\",\n *     serviceName: \"connectrpc.eliza.v1.ElizaService\",\n *     methodName: \"Say\",\n *     input: {\n *       sentence: \"hello there\",\n *     },\n *     cardinality: \"finite\",\n *   }\n * ]\n */\nexport type ConnectQueryKey<OutputMessage extends DescMessage = DescMessage> =\n  | InfiniteConnectQueryKey<OutputMessage>\n  | FiniteConnectQueryKey<OutputMessage>\n  | [\n      \"connect-query\",\n      SharedConnectQueryOptions & {\n        cardinality: undefined;\n      },\n    ];\n\ntype KeyParamsForMethod<Desc extends DescMethod> = {\n  /**\n   * Set `serviceName` and `methodName` in the key.\n   */\n  schema: Desc;\n  /**\n   * Set `input` in the key:\n   * - If a SkipToken is provided, `input` is \"skipped\".\n   * - If an init shape is provided, `input` is set to a message key.\n   * - If omitted or undefined, `input` is not set in the key.\n   */\n  input?: MessageInitShape<Desc[\"input\"]> | SkipToken | undefined;\n  /**\n   * Set `transport` in the key.\n   */\n  transport?: Transport;\n  /**\n   * Set `cardinality` in the key - undefined is used for filters to match both finite and infinite queries.\n   */\n  cardinality: \"finite\" | \"infinite\" | undefined;\n  /**\n   * If omit the field with this name from the key for infinite queries.\n   */\n  pageParamKey?: MessagePageParamKey<MessageInitShape<Desc[\"input\"]>>;\n  /**\n   * Set `headers` in the key.\n   * Note that invalid HTTP header names will raise a TypeError, and that the Set-Cookie header is not supported.\n   */\n  headers?: HeadersInit;\n};\n\ntype KeyParamsForService<Desc extends DescService> = {\n  /**\n   * Set `serviceName` in the key, and omit `methodName`.\n   */\n  schema: Desc;\n  /**\n   * Set `transport` in the key.\n   */\n  transport?: Transport;\n  /**\n   * Set `cardinality` in the key - undefined is used for filters to match both finite and infinite queries.\n   */\n  cardinality: \"finite\" | \"infinite\" | undefined;\n};\n\n/**\n * TanStack Query manages query caching for you based on query keys. In Connect Query, keys are structured, and can easily be created using this factory function.\n *\n * When you make a query, a unique key is automatically created from the schema, input message, and transport. For example:\n *\n * ```ts\n * import { useQuery } from \"@connectrpc/connect-query\";\n *\n * useQuery(ElizaService.method.say, { sentence: \"hello\" });\n *\n * // creates the key:\n * [\n *   \"connect-query\",\n *   {\n *     transport: \"t1\",\n *     serviceName: \"connectrpc.eliza.v1.ElizaService\",\n *     methodName: \"Say\",\n *     input: { sentence: \"hello\" },\n *     cardinality: \"finite\",\n *   }\n * ]\n * ```\n *\n * The same key can be created manually with this factory:\n *\n * ```ts\n * createConnectQueryKey({\n *   transport: myTransportReference,\n *   schema: ElizaService.method.say,\n *   input: { sentence: \"hello\" }\n * });\n * ```\n *\n * Note that the factory allows to create partial keys that can be used to filter queries. For example, you can create a key without a transport, any cardinality, any input message, or with a partial input message.\n *\n * @see ConnectQueryKey for information on the components of Connect-Query's keys.\n */\nexport function createConnectQueryKey<\n  I extends DescMessage,\n  O extends DescMessage,\n>(\n  params: KeyParamsForMethod<DescMethodUnary<I, O>> & {\n    cardinality: \"finite\";\n  },\n): FiniteConnectQueryKey<O>;\nexport function createConnectQueryKey<\n  I extends DescMessage,\n  O extends DescMessage,\n>(\n  params: KeyParamsForMethod<DescMethodUnary<I, O>> & {\n    cardinality: \"infinite\";\n  },\n): InfiniteConnectQueryKey<O>;\nexport function createConnectQueryKey<\n  I extends DescMessage,\n  O extends DescMessage,\n>(\n  params: KeyParamsForMethod<DescMethodUnary<I, O>> & {\n    cardinality: undefined;\n  },\n): ConnectQueryKey<O>;\nexport function createConnectQueryKey<\n  O extends DescMessage,\n  Desc extends DescService,\n>(params: KeyParamsForService<Desc>): ConnectQueryKey<O>;\nexport function createConnectQueryKey<\n  I extends DescMessage,\n  O extends DescMessage,\n  Desc extends DescService,\n>(\n  params: KeyParamsForMethod<DescMethodUnary<I, O>> | KeyParamsForService<Desc>,\n): ConnectQueryKey<O> {\n  const props: {\n    serviceName: string;\n    methodName?: string;\n    transport?: string;\n    cardinality?: \"finite\" | \"infinite\";\n    input?: \"skipped\" | Record<string, unknown>;\n    headers?: Record<string, string>;\n  } =\n    params.schema.kind == \"rpc\"\n      ? {\n          serviceName: params.schema.parent.typeName,\n          methodName: params.schema.name,\n        }\n      : {\n          serviceName: params.schema.typeName,\n        };\n  if (params.transport !== undefined) {\n    props.transport = createTransportKey(params.transport);\n  }\n  if (params.cardinality !== undefined) {\n    props.cardinality = params.cardinality;\n  }\n  if (params.schema.kind == \"rpc\" && \"input\" in params) {\n    if (typeof params.input == \"symbol\") {\n      props.input = \"skipped\";\n    } else if (params.input !== undefined) {\n      props.input = createMessageKey(\n        params.schema.input,\n        params.input,\n        params.pageParamKey,\n      );\n    }\n  }\n  if (\n    params.schema.kind === \"rpc\" &&\n    \"headers\" in params &&\n    params.headers !== undefined\n  ) {\n    props.headers = createHeadersKey(params.headers);\n  }\n  return [\"connect-query\", props] as ConnectQueryKey<O>;\n}\n\n/**\n * Creates a record of headers from a HeadersInit object.\n *\n */\nfunction createHeadersKey(headers: HeadersInit): Record<string, string> {\n  const result: Record<string, string> = {};\n\n  for (const [key, value] of new Headers(headers)) {\n    result[key] = value;\n  }\n  return result;\n}\n"
  },
  {
    "path": "packages/connect-query-core/src/create-infinite-query-options.test.ts",
    "content": "// Copyright 2021-2023 The Connect Authors\n//\n// Licensed under the Apache License, Version 2.0 (the \"License\");\n// you may not use this file except in compliance with the License.\n// You may obtain a copy of the License at\n//\n//      http://www.apache.org/licenses/LICENSE-2.0\n//\n// Unless required by applicable law or agreed to in writing, software\n// distributed under the License is distributed on an \"AS IS\" BASIS,\n// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n// See the License for the specific language governing permissions and\n// limitations under the License.\n\nimport { mockEliza } from \"test-utils\";\nimport { ListService } from \"test-utils/gen/list_pb.js\";\nimport { describe, expect, expectTypeOf, it } from \"vitest\";\n\nimport { createInfiniteQueryOptions, skipToken } from \"./index.js\";\n\nconst listMethod = ListService.method.list;\nconst nestedListMethod = ListService.method.nestedList;\n\nconst mockedElizaTransport = mockEliza();\n\ndescribe(\"createInfiniteQueryOptions\", () => {\n  it(\"honors skipToken\", () => {\n    const opt = createInfiniteQueryOptions(listMethod, skipToken, {\n      transport: mockedElizaTransport,\n      getNextPageParam: (lastPage) => lastPage.page + 1n,\n      pageParamKey: \"page\",\n    });\n    expect(opt.queryFn).toBe(skipToken);\n    expectTypeOf(opt.queryFn).toEqualTypeOf(skipToken);\n  });\n\n  it(\"allows nested pageParamKey as key path array\", () => {\n    const initialPage = 10n;\n    const opt = createInfiniteQueryOptions(\n      nestedListMethod,\n      {\n        nested: {\n          page: initialPage,\n        },\n      },\n      {\n        transport: mockedElizaTransport,\n        getNextPageParam: (lastPage) => (lastPage.nested?.page ?? 0n) + 1n,\n        pageParamKey: \"nested.page\",\n      },\n    );\n    expect(opt.initialPageParam).toBe(initialPage);\n    expect(opt.queryKey[1].input).toStrictEqual({ nested: {} });\n    expectTypeOf(opt.initialPageParam).toEqualTypeOf<bigint | undefined>();\n  });\n});\n"
  },
  {
    "path": "packages/connect-query-core/src/create-infinite-query-options.ts",
    "content": "// Copyright 2021-2023 The Connect Authors\n//\n// Licensed under the Apache License, Version 2.0 (the \"License\");\n// you may not use this file except in compliance with the License.\n// You may obtain a copy of the License at\n//\n//      http://www.apache.org/licenses/LICENSE-2.0\n//\n// Unless required by applicable law or agreed to in writing, software\n// distributed under the License is distributed on an \"AS IS\" BASIS,\n// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n// See the License for the specific language governing permissions and\n// limitations under the License.\n\nimport type {\n  DescMessage,\n  DescMethodUnary,\n  MessageInitShape,\n  MessageShape,\n} from \"@bufbuild/protobuf\";\nimport type { Transport } from \"@connectrpc/connect\";\nimport type {\n  GetNextPageParamFunction,\n  QueryFunction,\n  SkipToken,\n} from \"@tanstack/query-core\";\nimport { skipToken } from \"@tanstack/query-core\";\n\nimport { callUnaryMethod } from \"./call-unary-method.js\";\nimport {\n  type ConnectQueryKey,\n  createConnectQueryKey,\n} from \"./connect-query-key.js\";\nimport {\n  getValueAtPath,\n  type MessageInitWithPageParam,\n  type MessagePageParamKey,\n  type MessagePageParamValue,\n  setValueAtPath,\n} from \"./page-param-key.js\";\nimport { createStructuralSharing } from \"./structural-sharing.js\";\nimport { assert } from \"./utils.js\";\n\n/**\n * Return type of createInfiniteQueryOptions assuming SkipToken was not provided.\n */\nexport interface InfiniteQueryOptions<\n  I extends DescMessage,\n  O extends DescMessage,\n  ParamKey extends MessagePageParamKey<MessageInitShape<I>>,\n> {\n  getNextPageParam: ConnectInfiniteQueryOptions<\n    I,\n    O,\n    ParamKey\n  >[\"getNextPageParam\"];\n  queryKey: ConnectQueryKey<O>;\n  queryFn: QueryFunction<\n    MessageShape<O>,\n    ConnectQueryKey<O>,\n    MessagePageParamValue<MessageInitShape<I>, ParamKey>\n  >;\n  structuralSharing: (oldData: unknown, newData: unknown) => unknown;\n  initialPageParam: MessagePageParamValue<MessageInitShape<I>, ParamKey>;\n}\n\n/**\n * Return type of createInfiniteQueryOptions when SkipToken is provided\n */\nexport interface InfiniteQueryOptionsWithSkipToken<\n  I extends DescMessage,\n  O extends DescMessage,\n  ParamKey extends MessagePageParamKey<MessageInitShape<I>>,\n> extends Omit<InfiniteQueryOptions<I, O, ParamKey>, \"queryFn\"> {\n  queryFn: SkipToken;\n}\n\n/**\n * Options specific to connect-query\n */\nexport interface ConnectInfiniteQueryOptions<\n  I extends DescMessage,\n  O extends DescMessage,\n  ParamKey extends MessagePageParamKey<MessageInitShape<I>>,\n> {\n  /** Defines which part of the input should be considered the page param */\n  pageParamKey: ParamKey;\n  /** Determines the next page. */\n  getNextPageParam: GetNextPageParamFunction<\n    MessagePageParamValue<MessageInitShape<I>, ParamKey>,\n    MessageShape<O>\n  >;\n  headers?: HeadersInit;\n}\n\n// eslint-disable-next-line @typescript-eslint/max-params -- we have 4 required arguments\nfunction createUnaryInfiniteQueryFn<\n  I extends DescMessage,\n  O extends DescMessage,\n  ParamKey extends MessagePageParamKey<MessageInitShape<I>>,\n>(\n  transport: Transport,\n  schema: DescMethodUnary<I, O>,\n  input: MessageInitShape<I>,\n  {\n    pageParamKey,\n  }: {\n    pageParamKey: ParamKey;\n  },\n): QueryFunction<\n  MessageShape<O>,\n  ConnectQueryKey<O>,\n  MessagePageParamValue<MessageInitShape<I>, ParamKey>\n> {\n  return async (context) => {\n    assert(\"pageParam\" in context, \"pageParam must be part of context\");\n\n    const inputCombinedWithPageParam = setValueAtPath(\n      input,\n      pageParamKey as MessagePageParamKey<Record<string, unknown>>,\n      context.pageParam,\n    ) as MessageInitShape<I>;\n    return callUnaryMethod(transport, schema, inputCombinedWithPageParam, {\n      signal: context.signal,\n      headers: context.queryKey[1].headers,\n    });\n  };\n}\n\n/**\n * Query the method provided. Maps to useInfiniteQuery on tanstack/react-query\n */\nexport function createInfiniteQueryOptions<\n  I extends DescMessage,\n  O extends DescMessage,\n  const ParamKey extends MessagePageParamKey<MessageInitShape<I>>,\n>(\n  schema: DescMethodUnary<I, O>,\n  input: MessageInitWithPageParam<MessageInitShape<I>, ParamKey>,\n  {\n    transport,\n    getNextPageParam,\n    pageParamKey,\n    headers,\n  }: ConnectInfiniteQueryOptions<I, O, ParamKey> & { transport: Transport },\n): InfiniteQueryOptions<I, O, ParamKey>;\nexport function createInfiniteQueryOptions<\n  I extends DescMessage,\n  O extends DescMessage,\n  const ParamKey extends MessagePageParamKey<MessageInitShape<I>>,\n>(\n  schema: DescMethodUnary<I, O>,\n  input: SkipToken,\n  {\n    transport,\n    getNextPageParam,\n    pageParamKey,\n    headers,\n  }: ConnectInfiniteQueryOptions<I, O, ParamKey> & { transport: Transport },\n): InfiniteQueryOptionsWithSkipToken<I, O, ParamKey>;\nexport function createInfiniteQueryOptions<\n  I extends DescMessage,\n  O extends DescMessage,\n  const ParamKey extends MessagePageParamKey<MessageInitShape<I>>,\n>(\n  schema: DescMethodUnary<I, O>,\n  input: SkipToken | MessageInitWithPageParam<MessageInitShape<I>, ParamKey>,\n  {\n    transport,\n    getNextPageParam,\n    pageParamKey,\n    headers,\n  }: ConnectInfiniteQueryOptions<I, O, ParamKey> & { transport: Transport },\n):\n  | InfiniteQueryOptions<I, O, ParamKey>\n  | InfiniteQueryOptionsWithSkipToken<I, O, ParamKey>;\nexport function createInfiniteQueryOptions<\n  I extends DescMessage,\n  O extends DescMessage,\n  const ParamKey extends MessagePageParamKey<MessageInitShape<I>>,\n>(\n  schema: DescMethodUnary<I, O>,\n  input: SkipToken | MessageInitWithPageParam<MessageInitShape<I>, ParamKey>,\n  {\n    transport,\n    getNextPageParam,\n    pageParamKey,\n    headers,\n  }: ConnectInfiniteQueryOptions<I, O, ParamKey> & { transport: Transport },\n):\n  | InfiniteQueryOptions<I, O, ParamKey>\n  | InfiniteQueryOptionsWithSkipToken<I, O, ParamKey> {\n  const queryKey = createConnectQueryKey({\n    cardinality: \"infinite\",\n    schema,\n    transport,\n    input,\n    pageParamKey,\n    headers,\n  });\n  const structuralSharing = createStructuralSharing(schema.output);\n  const queryFn =\n    input === skipToken\n      ? skipToken\n      : createUnaryInfiniteQueryFn(transport, schema, input, {\n          pageParamKey,\n        });\n  return {\n    getNextPageParam,\n    initialPageParam:\n      input === skipToken\n        ? (undefined as MessagePageParamValue<MessageInitShape<I>, ParamKey>)\n        : (getValueAtPath(\n            input,\n            pageParamKey as MessagePageParamKey<Record<string, unknown>>,\n          ) as MessagePageParamValue<MessageInitShape<I>, ParamKey>),\n    queryKey,\n    queryFn,\n    structuralSharing,\n  };\n}\n"
  },
  {
    "path": "packages/connect-query-core/src/create-query-options.test.ts",
    "content": "// Copyright 2021-2023 The Connect Authors\n//\n// Licensed under the Apache License, Version 2.0 (the \"License\");\n// you may not use this file except in compliance with the License.\n// You may obtain a copy of the License at\n//\n//      http://www.apache.org/licenses/LICENSE-2.0\n//\n// Unless required by applicable law or agreed to in writing, software\n// distributed under the License is distributed on an \"AS IS\" BASIS,\n// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n// See the License for the specific language governing permissions and\n// limitations under the License.\n\nimport { skipToken as tanstackSkipToken } from \"@tanstack/query-core\";\nimport { mockEliza } from \"test-utils\";\nimport { ElizaService } from \"test-utils/gen/eliza_pb.js\";\nimport { describe, expect, expectTypeOf, it } from \"vitest\";\n\nimport { createConnectQueryKey } from \"./connect-query-key.js\";\nimport { createQueryOptions } from \"./create-query-options.js\";\nimport { skipToken } from \"./index.js\";\n\n// TODO: maybe create a helper to take a service and method and generate this.\nconst sayMethodDescriptor = ElizaService.method.say;\n\nconst mockedElizaTransport = mockEliza();\n\ndescribe(\"createQueryOptions\", () => {\n  it(\"honors skipToken\", () => {\n    const opt = createQueryOptions(sayMethodDescriptor, skipToken, {\n      transport: mockedElizaTransport,\n    });\n    expect(opt.queryFn).toBe(skipToken);\n    expectTypeOf(opt.queryFn).toEqualTypeOf(skipToken);\n  });\n\n  it(\"honors skipToken directly from tanstack\", () => {\n    const opt = createQueryOptions(sayMethodDescriptor, tanstackSkipToken, {\n      transport: mockedElizaTransport,\n    });\n    expect(opt.queryFn).toBe(tanstackSkipToken);\n  });\n\n  it(\"sets queryKey\", () => {\n    const want = createConnectQueryKey({\n      schema: sayMethodDescriptor,\n      input: { sentence: \"hi\" },\n      transport: mockedElizaTransport,\n      cardinality: \"finite\",\n      headers: {\n        \"x-custom-header\": \"custom-value\",\n      },\n    });\n    const opt = createQueryOptions(\n      sayMethodDescriptor,\n      { sentence: \"hi\" },\n      {\n        transport: mockedElizaTransport,\n        headers: {\n          \"x-custom-header\": \"custom-value\",\n        },\n      },\n    );\n    expect(opt.queryKey).toStrictEqual(want);\n  });\n\n  it(\"ensures type safety of parameters\", () => {\n    // @ts-expect-error(2322) cannot provide invalid parameters\n    createQueryOptions(\n      sayMethodDescriptor,\n      {\n        sentence: 1,\n      },\n      {\n        transport: mockedElizaTransport,\n      },\n    );\n  });\n});\n"
  },
  {
    "path": "packages/connect-query-core/src/create-query-options.ts",
    "content": "// Copyright 2021-2023 The Connect Authors\n//\n// Licensed under the Apache License, Version 2.0 (the \"License\");\n// you may not use this file except in compliance with the License.\n// You may obtain a copy of the License at\n//\n//      http://www.apache.org/licenses/LICENSE-2.0\n//\n// Unless required by applicable law or agreed to in writing, software\n// distributed under the License is distributed on an \"AS IS\" BASIS,\n// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n// See the License for the specific language governing permissions and\n// limitations under the License.\n\nimport type {\n  DescMessage,\n  DescMethodUnary,\n  MessageInitShape,\n  MessageShape,\n} from \"@bufbuild/protobuf\";\nimport { create } from \"@bufbuild/protobuf\";\nimport type { Transport } from \"@connectrpc/connect\";\nimport type { QueryFunction, SkipToken } from \"@tanstack/query-core\";\nimport { skipToken } from \"@tanstack/query-core\";\n\nimport { callUnaryMethod } from \"./call-unary-method.js\";\nimport type { ConnectQueryKey } from \"./connect-query-key.js\";\nimport { createConnectQueryKey } from \"./connect-query-key.js\";\nimport { createStructuralSharing } from \"./structural-sharing.js\";\n\n/**\n * Return type of createQueryOptions\n */\nexport interface QueryOptions<O extends DescMessage> {\n  queryKey: ConnectQueryKey<O>;\n  queryFn: QueryFunction<MessageShape<O>, ConnectQueryKey<O>>;\n  structuralSharing: (oldData: unknown, newData: unknown) => unknown;\n}\n\nexport interface QueryOptionsWithSkipToken<O extends DescMessage>\n  extends Omit<QueryOptions<O>, \"queryFn\"> {\n  queryFn: SkipToken;\n}\n\nfunction createUnaryQueryFn<I extends DescMessage, O extends DescMessage>(\n  transport: Transport,\n  schema: DescMethodUnary<I, O>,\n  input: MessageInitShape<I> | undefined,\n): QueryFunction<MessageShape<O>, ConnectQueryKey<O>> {\n  return async (context) => {\n    return callUnaryMethod(transport, schema, input, {\n      signal: context.signal,\n      headers: context.queryKey[1].headers,\n    });\n  };\n}\n\n/**\n * Creates all options required to make a query. Useful in combination with `useQueries` from tanstack/react-query.\n */\nexport function createQueryOptions<\n  I extends DescMessage,\n  O extends DescMessage,\n>(\n  schema: DescMethodUnary<I, O>,\n  input: MessageInitShape<I> | undefined,\n  {\n    transport,\n    headers,\n  }: {\n    transport: Transport;\n    headers?: HeadersInit;\n  },\n): QueryOptions<O>;\nexport function createQueryOptions<\n  I extends DescMessage,\n  O extends DescMessage,\n>(\n  schema: DescMethodUnary<I, O>,\n  input: SkipToken,\n  {\n    transport,\n    headers,\n  }: {\n    transport: Transport;\n    headers?: HeadersInit;\n  },\n): QueryOptionsWithSkipToken<O>;\nexport function createQueryOptions<\n  I extends DescMessage,\n  O extends DescMessage,\n>(\n  schema: DescMethodUnary<I, O>,\n  input: SkipToken | MessageInitShape<I> | undefined,\n  {\n    transport,\n    headers,\n  }: {\n    transport: Transport;\n    headers?: HeadersInit;\n  },\n): QueryOptions<O> | QueryOptionsWithSkipToken<O>;\nexport function createQueryOptions<\n  I extends DescMessage,\n  O extends DescMessage,\n>(\n  schema: DescMethodUnary<I, O>,\n  input: SkipToken | MessageInitShape<I> | undefined,\n  {\n    transport,\n    headers,\n  }: {\n    transport: Transport;\n    headers?: HeadersInit;\n  },\n): QueryOptions<O> | QueryOptionsWithSkipToken<O> {\n  const queryKey = createConnectQueryKey({\n    schema,\n    input: input ?? create(schema.input),\n    transport,\n    cardinality: \"finite\",\n    headers,\n  });\n  const structuralSharing = createStructuralSharing(schema.output);\n  const queryFn =\n    input === skipToken\n      ? skipToken\n      : createUnaryQueryFn(transport, schema, input);\n  return {\n    queryKey,\n    queryFn,\n    structuralSharing,\n  };\n}\n"
  },
  {
    "path": "packages/connect-query-core/src/index.ts",
    "content": "// Copyright 2021-2023 The Connect Authors\n//\n// Licensed under the Apache License, Version 2.0 (the \"License\");\n// you may not use this file except in compliance with the License.\n// You may obtain a copy of the License at\n//\n//      http://www.apache.org/licenses/LICENSE-2.0\n//\n// Unless required by applicable law or agreed to in writing, software\n// distributed under the License is distributed on an \"AS IS\" BASIS,\n// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n// See the License for the specific language governing permissions and\n// limitations under the License.\n\nexport type { ConnectQueryKey } from \"./connect-query-key.js\";\nexport { createConnectQueryKey } from \"./connect-query-key.js\";\nexport { createProtobufSafeUpdater } from \"./utils.js\";\nexport type { ConnectUpdater } from \"./utils.js\";\nexport { callUnaryMethod } from \"./call-unary-method.js\";\nexport { createInfiniteQueryOptions } from \"./create-infinite-query-options.js\";\nexport type {\n  ConnectInfiniteQueryOptions,\n  InfiniteQueryOptionsWithSkipToken,\n  InfiniteQueryOptions,\n} from \"./create-infinite-query-options.js\";\nexport type {\n  MessageInitWithPageParam,\n  MessagePageParamKey,\n  MessagePageParamValue,\n} from \"./page-param-key.js\";\nexport { createQueryOptions } from \"./create-query-options.js\";\nexport type {\n  QueryOptions,\n  QueryOptionsWithSkipToken,\n} from \"./create-query-options.js\";\nexport { addStaticKeyToTransport } from \"./transport-key.js\";\nexport type { SkipToken } from \"@tanstack/query-core\";\nexport { skipToken } from \"@tanstack/query-core\";\n"
  },
  {
    "path": "packages/connect-query-core/src/message-key.test.ts",
    "content": "// Copyright 2021-2023 The Connect Authors\n//\n// Licensed under the Apache License, Version 2.0 (the \"License\");\n// you may not use this file except in compliance with the License.\n// You may obtain a copy of the License at\n//\n//      http://www.apache.org/licenses/LICENSE-2.0\n//\n// Unless required by applicable law or agreed to in writing, software\n// distributed under the License is distributed on an \"AS IS\" BASIS,\n// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n// See the License for the specific language governing permissions and\n// limitations under the License.\n\nimport { create } from \"@bufbuild/protobuf\";\nimport { Proto2MessageSchema } from \"test-utils/gen/proto2_pb.js\";\nimport { Proto3Enum, Proto3MessageSchema } from \"test-utils/gen/proto3_pb.js\";\nimport { describe, expect, it } from \"vitest\";\n\nimport { createMessageKey } from \"./message-key.js\";\n\ndescribe(\"message key\", () => {\n  it(\"omits proto3 default values\", () => {\n    const schema = Proto3MessageSchema;\n    const message = create(schema);\n    const key = createMessageKey(schema, message);\n    expect(key).toStrictEqual({});\n  });\n  it(\"omits proto2 default values\", () => {\n    const schema = Proto2MessageSchema;\n    const message = create(schema);\n    const key = createMessageKey(schema, message);\n    expect(key).toStrictEqual({});\n  });\n  it(\"omits the pageParamKey\", () => {\n    const schema = Proto3MessageSchema;\n    const message = create(schema, {\n      int32Field: 123,\n      stringField: \"abc\",\n    });\n    const key = createMessageKey(schema, message, \"int32Field\");\n    expect(key).toStrictEqual({\n      stringField: \"abc\",\n    });\n  });\n\n  it(\"omits nested pageParamKey\", () => {\n    const key = createMessageKey(\n      Proto3MessageSchema,\n      {\n        messageField: {\n          int32Field: 1,\n          stringField: \"abc\",\n        },\n      },\n      \"messageField.int32Field\",\n    );\n    expect(key).toStrictEqual({\n      messageField: {\n        stringField: \"abc\",\n      },\n    });\n  });\n  it(\"converts as expected\", () => {\n    const key = createMessageKey(Proto3MessageSchema, {\n      int64Field: 123n,\n      bytesField: new Uint8Array([0xde, 0xad, 0xbe, 0xef]),\n      doubleField: Number.NaN,\n      messageField: {\n        doubleField: Infinity,\n        messageField: {\n          doubleField: -Infinity,\n        },\n      },\n      boolField: true,\n      enumField: Proto3Enum.YES,\n      repeatedStringField: [\"a\", \"b\"],\n      repeatedMessageField: [{ int64Field: 456n }],\n      repeatedEnumField: [Proto3Enum.YES, Proto3Enum.NO],\n      either: {\n        case: \"oneofInt32Field\",\n        value: 123,\n      },\n      mapStringInt64Field: {\n        foo: 123n,\n      },\n      mapStringMessageField: {\n        foo: {\n          int64Field: 123n,\n        },\n      },\n      mapStringEnumField: {\n        foo: Proto3Enum.YES,\n      },\n    });\n    expect(key).toStrictEqual({\n      int64Field: \"123\",\n      bytesField: \"3q2+7w\",\n      doubleField: \"NaN\",\n      messageField: {\n        doubleField: \"Infinity\",\n        messageField: {\n          doubleField: \"-Infinity\",\n        },\n      },\n      boolField: true,\n      enumField: 1,\n      repeatedStringField: [\"a\", \"b\"],\n      repeatedMessageField: [{ int64Field: \"456\" }],\n      repeatedEnumField: [1, 2],\n      oneofInt32Field: 123,\n      mapStringInt64Field: {\n        foo: \"123\",\n      },\n      mapStringMessageField: {\n        foo: {\n          int64Field: \"123\",\n        },\n      },\n      mapStringEnumField: {\n        foo: 1,\n      },\n    });\n  });\n  it(\"sorts map keys\", () => {\n    const key = createMessageKey(Proto3MessageSchema, {\n      mapStringInt64Field: {\n        b: 2n,\n        a: 1n,\n      },\n    });\n    const mapKeys =\n      typeof key.mapStringInt64Field == \"object\" &&\n      key.mapStringInt64Field !== null\n        ? Object.keys(key.mapStringInt64Field)\n        : [];\n    expect(mapKeys).toStrictEqual([\"a\", \"b\"]);\n  });\n  it(\"sorts properties by protobuf source order\", () => {\n    const key = createMessageKey(Proto3MessageSchema, {\n      boolField: true,\n      stringField: \"a\",\n    });\n    expect(Object.keys(key)).toStrictEqual([\"stringField\", \"boolField\"]);\n  });\n});\n"
  },
  {
    "path": "packages/connect-query-core/src/message-key.ts",
    "content": "// Copyright 2021-2023 The Connect Authors\n//\n// Licensed under the Apache License, Version 2.0 (the \"License\");\n// you may not use this file except in compliance with the License.\n// You may obtain a copy of the License at\n//\n//      http://www.apache.org/licenses/LICENSE-2.0\n//\n// Unless required by applicable law or agreed to in writing, software\n// distributed under the License is distributed on an \"AS IS\" BASIS,\n// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n// See the License for the specific language governing permissions and\n// limitations under the License.\n\nimport type { DescMessage, MessageInitShape } from \"@bufbuild/protobuf\";\nimport { create } from \"@bufbuild/protobuf\";\nimport type {\n  ReflectList,\n  ReflectMap,\n  ReflectMessage,\n} from \"@bufbuild/protobuf/reflect\";\nimport { reflect } from \"@bufbuild/protobuf/reflect\";\nimport { base64Encode } from \"@bufbuild/protobuf/wire\";\n\nimport {\n  pageParamPathSegments,\n  type MessagePageParamKey,\n} from \"./page-param-key.js\";\n\n/**\n * For any given message, create an object that is suitable for a Query Key in\n * TanStack Query:\n *\n * - Default values are omitted (both implicit and explicit field presence).\n * - NaN, Infinity, and -Infinity are converted to a string.\n * - Uint8Array is encoded to a string with Base64.\n * - BigInt values are converted to a string.\n * - Properties are sorted by Protobuf source order.\n * - Map keys are sorted with Array.sort.\n *\n * If pageParamKey is provided, omit the field with this name from the key.\n */\nexport function createMessageKey<\n  Desc extends DescMessage,\n  PageParamKey extends MessagePageParamKey<MessageInitShape<Desc>>,\n>(\n  schema: Desc,\n  value: MessageInitShape<Desc>,\n  pageParamKey?: PageParamKey,\n): Record<string, unknown> {\n  const pageParamPath =\n    pageParamKey === undefined\n      ? undefined\n      : pageParamPathSegments(\n          pageParamKey as MessagePageParamKey<Record<string, unknown>>,\n        );\n  return messageKey(reflect(schema, create(schema, value)), pageParamPath);\n}\n\nfunction scalarKey(value: unknown): unknown {\n  if (typeof value == \"bigint\") {\n    return String(value);\n  }\n  if (typeof value == \"number\" && !isFinite(value)) {\n    return String(value);\n  }\n  if (value instanceof Uint8Array) {\n    return base64Encode(value, \"std_raw\");\n  }\n  return value;\n}\n\nfunction listKey(list: ReflectList): unknown[] {\n  const arr = Array.from(list);\n  const { listKind } = list.field();\n  if (listKind == \"scalar\") {\n    return arr.map(scalarKey);\n  }\n  if (listKind == \"message\") {\n    // eslint-disable-next-line @typescript-eslint/no-use-before-define -- circular reference\n    return (arr as ReflectMessage[]).map((m) => messageKey(m));\n  }\n  return arr;\n}\n\nfunction mapKey(map: ReflectMap): Record<string, unknown> {\n  // eslint-disable-next-line @typescript-eslint/require-array-sort-compare -- we want the standard behavior\n  return Array.from(map.keys())\n    .sort()\n    .reduce<Record<string, unknown>>((result, k) => {\n      switch (map.field().mapKind) {\n        case \"message\":\n          // eslint-disable-next-line @typescript-eslint/no-use-before-define -- circular reference\n          result[k as string] = messageKey(map.get(k) as ReflectMessage);\n          break;\n        case \"scalar\":\n          result[k as string] = scalarKey(map.get(k));\n          break;\n        case \"enum\":\n          result[k as string] = map.get(k);\n          break;\n      }\n      return result;\n    }, {});\n}\n\nfunction messageKey(\n  message: ReflectMessage,\n  pageParamPath?: string[],\n): Record<string, unknown> {\n  const result: Record<string, unknown> = {};\n  for (const f of message.sortedFields) {\n    if (!message.isSet(f)) {\n      continue;\n    }\n    const includesPageParam =\n      pageParamPath !== undefined && f.localName === pageParamPath[0];\n    if (includesPageParam && pageParamPath.length === 1) {\n      continue;\n    }\n    switch (f.fieldKind) {\n      case \"scalar\":\n        result[f.localName] = scalarKey(message.get(f));\n        break;\n      case \"enum\":\n        result[f.localName] = message.get(f);\n        break;\n      case \"list\":\n        result[f.localName] = listKey(message.get(f));\n        break;\n      case \"map\":\n        result[f.localName] = mapKey(message.get(f));\n        break;\n      case \"message\":\n        result[f.localName] = messageKey(\n          message.get(f),\n          includesPageParam ? pageParamPath.slice(1) : undefined,\n        );\n        break;\n    }\n  }\n  return result;\n}\n"
  },
  {
    "path": "packages/connect-query-core/src/page-param-key.ts",
    "content": "// Copyright 2021-2023 The Connect Authors\n//\n// Licensed under the Apache License, Version 2.0 (the \"License\");\n// you may not use this file except in compliance with the License.\n// You may obtain a copy of the License at\n//\n//      http://www.apache.org/licenses/LICENSE-2.0\n//\n// Unless required by applicable law or agreed to in writing, software\n// distributed under the License is distributed on an \"AS IS\" BASIS,\n// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n// See the License for the specific language governing permissions and\n// limitations under the License.\n\nimport type { Message } from \"@bufbuild/protobuf\";\n\ntype StringKeyOf<T> = Exclude<Extract<keyof T, string>, keyof Message>;\ntype PrevDepth = [never, 0, 1, 2, 3, 4, 5];\n\ntype CanDescend<T> = T extends readonly unknown[]\n  ? false\n  : T extends object\n    ? true\n    : false;\n\ntype MessagePageParamPathString<T, Depth extends number = 5> = Depth extends 0\n  ? never\n  : T extends object\n    ? {\n        [K in StringKeyOf<T>]: CanDescend<NonNullable<T[K]>> extends true\n          ?\n              | K\n              | `${K}.${MessagePageParamPathString<\n                  NonNullable<T[K]>,\n                  PrevDepth[Depth]\n                >}`\n          : K;\n      }[StringKeyOf<T>]\n    : never;\n\n/**\n * A page param key can be a root key,\n * or a dot-separated key path.\n */\nexport type MessagePageParamKey<T> = MessagePageParamPathString<T>;\n\ntype DotPathValue<T, P extends string> = P extends `${infer Head}.${infer Tail}`\n  ? Head extends StringKeyOf<T>\n    ? DotPathValue<NonNullable<T[Head]>, Tail>\n    : never\n  : P extends StringKeyOf<T>\n    ? T[P]\n    : never;\n\n/**\n * Resolves the value type at a page param key path.\n */\nexport type MessagePageParamValue<\n  T,\n  K extends MessagePageParamKey<T>,\n> = K extends string ? DotPathValue<T, K> : never;\n\ntype RootKey<K> = K extends `${infer Head}.${string}`\n  ? Head\n  : K extends StringKeyOf<Record<string, unknown>>\n    ? K\n    : never;\n\n/**\n * Requires the root object key for a page param path.\n */\nexport type MessageInitWithPageParam<T, K extends MessagePageParamKey<T>> = T &\n  Required<Pick<T, Extract<RootKey<K>, StringKeyOf<T>>>>;\n\nexport function pageParamPathSegments(\n  pageParamKey: MessagePageParamKey<Record<string, unknown>>,\n): string[] {\n  return pageParamKey.split(\".\");\n}\n\nexport function getValueAtPath(\n  value: Record<string, unknown>,\n  pageParamKey: MessagePageParamKey<Record<string, unknown>>,\n): unknown {\n  const path = pageParamPathSegments(pageParamKey);\n  let current: unknown = value;\n  for (const segment of path) {\n    if (\n      typeof current !== \"object\" ||\n      current === null ||\n      !(segment in current)\n    ) {\n      return undefined;\n    }\n    current = (current as Record<string, unknown>)[segment];\n  }\n  return current;\n}\n\nexport function setValueAtPath(\n  value: Record<string, unknown>,\n  pageParamKey: MessagePageParamKey<Record<string, unknown>>,\n  pageParam: unknown,\n): Record<string, unknown> {\n  const path = pageParamPathSegments(pageParamKey);\n  const result: Record<string, unknown> = { ...value };\n  let source: Record<string, unknown> = value;\n  let target = result;\n  for (let i = 0; i < path.length - 1; i++) {\n    const key = path[i];\n    const sourceNext = source[key];\n    const targetNext =\n      typeof sourceNext === \"object\" && sourceNext !== null\n        ? { ...(sourceNext as Record<string, unknown>) }\n        : {};\n    target[key] = targetNext;\n    target = targetNext;\n    source =\n      typeof sourceNext === \"object\" && sourceNext !== null\n        ? (sourceNext as Record<string, unknown>)\n        : {};\n  }\n  target[path[path.length - 1]] = pageParam;\n  return result;\n}\n"
  },
  {
    "path": "packages/connect-query-core/src/structural-sharing.test.ts",
    "content": "// Copyright 2021-2023 The Connect Authors\n//\n// Licensed under the Apache License, Version 2.0 (the \"License\");\n// you may not use this file except in compliance with the License.\n// You may obtain a copy of the License at\n//\n//      http://www.apache.org/licenses/LICENSE-2.0\n//\n// Unless required by applicable law or agreed to in writing, software\n// distributed under the License is distributed on an \"AS IS\" BASIS,\n// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n// See the License for the specific language governing permissions and\n// limitations under the License.\n\nimport { create } from \"@bufbuild/protobuf\";\nimport {\n  SayRequestSchema,\n  SayResponseSchema,\n} from \"test-utils/gen/eliza_pb.js\";\nimport { describe, expect, it } from \"vitest\";\n\nimport { createStructuralSharing } from \"./structural-sharing.js\";\n\ndescribe(\"structural sharing\", () => {\n  const schema = SayResponseSchema;\n  const fn = createStructuralSharing(schema);\n  it(\"returns old data if new data is equal\", () => {\n    const oldData = create(schema, { sentence: \"hi\" });\n    const newData = create(schema, { sentence: \"hi\" });\n    const result = fn(oldData, newData);\n    expect(result).toBe(oldData);\n  });\n  it(\"returns new data if not equal to old data\", () => {\n    const oldData = create(schema, { sentence: \"hi\" });\n    const newData = create(schema, { sentence: \"hello\" });\n    const result = fn(oldData, newData);\n    expect(result).toBe(newData);\n  });\n  it(\"returns new data if old data is undefined\", () => {\n    const oldData = undefined;\n    const newData = create(schema, { sentence: \"hello\" });\n    const result = fn(oldData, newData);\n    expect(result).toBe(newData);\n  });\n  it.each([123, null, create(SayRequestSchema, { sentence: \"hi\" })])(\n    \"returns new data for unexpected old data $#\",\n    (oldData) => {\n      const newData = create(schema, { sentence: \"hi\" });\n      const result = fn(oldData, newData);\n      expect(result).toBe(newData);\n    },\n  );\n  it.each([123, null, create(SayRequestSchema, { sentence: \"hi\" })])(\n    \"returns new data for unexpected new data $#\",\n    (newData) => {\n      const oldData = create(schema, { sentence: \"hi\" });\n      const result = fn(oldData, newData);\n      expect(result).toBe(newData);\n    },\n  );\n\n  it(\"allows returning old data if new data is equal\", () => {\n    const oldData = { count: 2 };\n    const newData = { count: 2 };\n    const result = fn(oldData, newData);\n    expect(result).toBe(oldData);\n  });\n});\n"
  },
  {
    "path": "packages/connect-query-core/src/structural-sharing.ts",
    "content": "// Copyright 2021-2023 The Connect Authors\n//\n// Licensed under the Apache License, Version 2.0 (the \"License\");\n// you may not use this file except in compliance with the License.\n// You may obtain a copy of the License at\n//\n//      http://www.apache.org/licenses/LICENSE-2.0\n//\n// Unless required by applicable law or agreed to in writing, software\n// distributed under the License is distributed on an \"AS IS\" BASIS,\n// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n// See the License for the specific language governing permissions and\n// limitations under the License.\n\nimport { type DescMessage, equals, isMessage } from \"@bufbuild/protobuf\";\nimport { replaceEqualDeep } from \"@tanstack/query-core\";\n\n/**\n * Returns a simplistic implementation for \"structural sharing\" for a Protobuf\n * message.\n *\n * To keep references intact between re-renders, we return the old version if it\n * equals the new version.\n *\n * See https://tanstack.com/query/latest/docs/framework/react/guides/render-optimizations#structural-sharing\n */\nexport function createStructuralSharing(\n  schema: DescMessage,\n  // eslint-disable-next-line @typescript-eslint/no-redundant-type-constituents -- matching the @tanstack/react-query types\n): (oldData: unknown | undefined, newData: unknown) => unknown {\n  return function (oldData, newData) {\n    if (!isMessage(oldData) || !isMessage(newData)) {\n      return replaceEqualDeep(oldData, newData);\n    }\n    if (!equals(schema, oldData, newData)) {\n      return newData;\n    }\n    return oldData;\n  };\n}\n"
  },
  {
    "path": "packages/connect-query-core/src/transport-key.test.ts",
    "content": "// Copyright 2021-2023 The Connect Authors\n//\n// Licensed under the Apache License, Version 2.0 (the \"License\");\n// you may not use this file except in compliance with the License.\n// You may obtain a copy of the License at\n//\n//      http://www.apache.org/licenses/LICENSE-2.0\n//\n// Unless required by applicable law or agreed to in writing, software\n// distributed under the License is distributed on an \"AS IS\" BASIS,\n// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n// See the License for the specific language governing permissions and\n// limitations under the License.\n\nimport { createConnectTransport } from \"@connectrpc/connect-web\";\nimport { describe, expect, it } from \"vitest\";\n\nimport {\n  addStaticKeyToTransport,\n  createTransportKey,\n} from \"./transport-key.js\";\n\ndescribe(\"transport key\", () => {\n  it(\"returns the same key for the same reference\", () => {\n    const transport = createConnectTransport({\n      baseUrl: \"https://example.com\",\n    });\n    const key1 = createTransportKey(transport);\n    const key2 = createTransportKey(transport);\n    expect(key1).toBe(key2);\n  });\n  it(\"creates a unique key for every reference\", () => {\n    const transport1 = createConnectTransport({\n      baseUrl: \"https://example.com\",\n    });\n    const transport2 = createConnectTransport({\n      baseUrl: \"https://example.com\",\n    });\n    const key1 = createTransportKey(transport1);\n    const key2 = createTransportKey(transport2);\n    expect(key1).not.toBe(key2);\n  });\n  it(\"allows override of key transport property\", () => {\n    const transport1 = addStaticKeyToTransport(\n      createConnectTransport({\n        baseUrl: \"https://example.com\",\n      }),\n      \"static-key\",\n    );\n    const key1 = createTransportKey(transport1);\n    expect(key1).toBe(\"static-key\");\n  });\n});\n"
  },
  {
    "path": "packages/connect-query-core/src/transport-key.ts",
    "content": "// Copyright 2021-2023 The Connect Authors\n//\n// Licensed under the Apache License, Version 2.0 (the \"License\");\n// you may not use this file except in compliance with the License.\n// You may obtain a copy of the License at\n//\n//      http://www.apache.org/licenses/LICENSE-2.0\n//\n// Unless required by applicable law or agreed to in writing, software\n// distributed under the License is distributed on an \"AS IS\" BASIS,\n// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n// See the License for the specific language governing permissions and\n// limitations under the License.\n\nimport type { Transport } from \"@connectrpc/connect\";\n\nconst staticKeySymbol = Symbol(\"static-key\");\n\nconst transportKeys = new WeakMap<Transport, string>();\nlet counter = 0;\n\ninterface TransportWithStaticKey extends Transport {\n  [staticKeySymbol]?: string;\n}\n\n/**\n * For a given Transport, create a string key that is suitable for a Query Key\n * in TanStack Query.\n *\n * This function will return a unique string for every reference.\n */\nexport function createTransportKey(transport: TransportWithStaticKey): string {\n  if (transport[staticKeySymbol] !== undefined) {\n    return transport[staticKeySymbol];\n  }\n  let key = transportKeys.get(transport);\n  if (key === undefined) {\n    key = `t${++counter}`;\n    transportKeys.set(transport, key);\n  }\n  return key;\n}\n\n/**\n * Enhances a given transport with a static query key that is used in any associated queries. This may be necessary\n * in SSR contexts where transports are used on both client and server but they need to be considered\n * the same when it comes to the query cache.\n */\nexport function addStaticKeyToTransport(\n  transport: Transport,\n  key: string,\n): TransportWithStaticKey {\n  return { ...transport, [staticKeySymbol]: key };\n}\n"
  },
  {
    "path": "packages/connect-query-core/src/utils.test.ts",
    "content": "// Copyright 2021-2023 The Connect Authors\n//\n// Licensed under the Apache License, Version 2.0 (the \"License\");\n// you may not use this file except in compliance with the License.\n// You may obtain a copy of the License at\n//\n//      http://www.apache.org/licenses/LICENSE-2.0\n//\n// Unless required by applicable law or agreed to in writing, software\n// distributed under the License is distributed on an \"AS IS\" BASIS,\n// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n// See the License for the specific language governing permissions and\n// limitations under the License.\n\nimport { create, isFieldSet, isMessage } from \"@bufbuild/protobuf\";\nimport { Proto2MessageSchema } from \"test-utils/gen/proto2_pb.js\";\nimport { describe, expect, it } from \"vitest\";\n\nimport {\n  assert,\n  createProtobufSafeUpdater,\n  isAbortController,\n} from \"./utils.js\";\n\ndescribe(\"assert\", () => {\n  const message = \"assertion message\";\n  it(\"throws on a false condition\", () => {\n    expect(() => {\n      assert(false, message);\n    }).toThrow(`Invalid assertion: ${message}`);\n  });\n\n  it(\"does not throw on a true condition\", () => {\n    expect(() => {\n      assert(true, message);\n    }).not.toThrow();\n  });\n});\n\ndescribe(\"isAbortController\", () => {\n  it(\"returns false for non-objects\", () => {\n    expect(isAbortController(true)).toBeFalsy();\n    expect(isAbortController(false)).toBeFalsy();\n    expect(isAbortController(0)).toBeFalsy();\n    expect(isAbortController(1)).toBeFalsy();\n    expect(isAbortController(\"a\")).toBeFalsy();\n    expect(isAbortController(undefined)).toBeFalsy();\n    expect(isAbortController([])).toBeFalsy();\n    expect(isAbortController(null)).toBeFalsy();\n  });\n\n  it(\"returns false for objects missing the AbortController properties\", () => {\n    expect(isAbortController({})).toBeFalsy();\n    expect(isAbortController({ signal: undefined })).toBeFalsy();\n    expect(isAbortController({ signal: null })).toBeFalsy();\n    expect(isAbortController({ signal: {} })).toBeFalsy();\n    expect(isAbortController({ signal: { aborted: undefined } })).toBeFalsy();\n    expect(isAbortController({ signal: { aborted: true } })).toBeFalsy();\n    expect(\n      isAbortController({ signal: { aborted: true }, abort: undefined }),\n    ).toBeFalsy();\n  });\n\n  it(\"returns true for the two necessary AbortController properties\", () => {\n    expect(\n      isAbortController({\n        signal: {\n          aborted: false,\n        },\n        abort: () => {},\n      }),\n    ).toBeTruthy();\n\n    expect(isAbortController(new AbortController())).toBeTruthy();\n  });\n});\n\ndescribe(\"createProtobufSafeUpdater\", () => {\n  describe(\"with update message\", () => {\n    const schema = { output: Proto2MessageSchema };\n    const update = create(Proto2MessageSchema, {\n      int32Field: 999,\n    });\n    const safeUpdater = createProtobufSafeUpdater(schema, update);\n    it(\"returns update message for previous value undefined\", () => {\n      const next = safeUpdater(undefined);\n      expect(next).toBe(update);\n    });\n    it(\"returns update message for previous value\", () => {\n      const prev = create(Proto2MessageSchema, {\n        int32Field: 123,\n      });\n      const next = safeUpdater(prev);\n      expect(next).toBe(update);\n    });\n  });\n\n  describe(\"with update message init\", () => {\n    const schema = { output: Proto2MessageSchema };\n    const update = {\n      int32Field: 999,\n    };\n    const safeUpdater = createProtobufSafeUpdater(schema, update);\n    it(\"returns update message for previous value undefined\", () => {\n      const next = safeUpdater(undefined);\n      expect(next?.int32Field).toBe(999);\n    });\n    it(\"returns update message for previous value\", () => {\n      const prev = create(Proto2MessageSchema, {\n        int32Field: 123,\n      });\n      const next = safeUpdater(prev);\n      expect(next?.$typeName).toBe(Proto2MessageSchema.typeName);\n      expect(next?.int32Field).toBe(999);\n    });\n  });\n\n  describe(\"with updater function\", () => {\n    const schema = { output: Proto2MessageSchema };\n    const safeUpdater = createProtobufSafeUpdater(schema, (prev) => {\n      if (prev === undefined) {\n        return undefined;\n      }\n      return {\n        ...prev,\n        int32Field: 999,\n      };\n    });\n    it(\"accepts undefined\", () => {\n      const next = safeUpdater(undefined);\n      expect(next).toBeUndefined();\n    });\n    it(\"accepts previous message\", () => {\n      const prev = create(Proto2MessageSchema, {\n        int32Field: 123,\n      });\n      const next = safeUpdater(prev);\n      expect(next).toBeDefined();\n    });\n    it(\"returns message\", () => {\n      const prev = create(Proto2MessageSchema);\n      const next = safeUpdater(prev);\n      expect(isMessage(next, Proto2MessageSchema)).toBe(true);\n    });\n    it(\"updates field\", () => {\n      const prev = create(Proto2MessageSchema);\n      const next = safeUpdater(prev);\n      expect(next?.int32Field).toBe(999);\n    });\n    it(\"keeps existing fields\", () => {\n      const prev = create(Proto2MessageSchema, {\n        stringField: \"abc\",\n      });\n      const next = safeUpdater(prev);\n      expect(next?.stringField).toBe(\"abc\");\n    });\n    describe(\"keeps field presence\", () => {\n      it(\"for unset field\", () => {\n        const prev = create(Proto2MessageSchema);\n        expect(isFieldSet(prev, Proto2MessageSchema.field.stringField)).toBe(\n          false,\n        );\n        const next = safeUpdater(prev);\n        const hasStringField =\n          next === undefined\n            ? undefined\n            : isFieldSet(next, Proto2MessageSchema.field.stringField);\n        expect(hasStringField).toBe(false);\n      });\n      it(\"for set field\", () => {\n        const prev = create(Proto2MessageSchema, {\n          stringField: \"abc\",\n        });\n        expect(isFieldSet(prev, Proto2MessageSchema.field.stringField)).toBe(\n          true,\n        );\n        const next = safeUpdater(prev);\n        const hasStringField =\n          next === undefined\n            ? undefined\n            : isFieldSet(next, Proto2MessageSchema.field.stringField);\n        expect(hasStringField).toBe(true);\n      });\n    });\n  });\n});\n"
  },
  {
    "path": "packages/connect-query-core/src/utils.ts",
    "content": "// Copyright 2021-2023 The Connect Authors\n//\n// Licensed under the Apache License, Version 2.0 (the \"License\");\n// you may not use this file except in compliance with the License.\n// You may obtain a copy of the License at\n//\n//      http://www.apache.org/licenses/LICENSE-2.0\n//\n// Unless required by applicable law or agreed to in writing, software\n// distributed under the License is distributed on an \"AS IS\" BASIS,\n// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n// See the License for the specific language governing permissions and\n// limitations under the License.\n\nimport type {\n  DescMessage,\n  DescMethodUnary,\n  MessageInitShape,\n  MessageShape,\n} from \"@bufbuild/protobuf\";\nimport { create, isMessage } from \"@bufbuild/protobuf\";\n\n/**\n * Throws an error with the provided message when the condition is `false`\n */\nexport function assert(condition: boolean, message: string): asserts condition {\n  if (!condition) {\n    throw new Error(`Invalid assertion: ${message}`);\n  }\n}\n\n/**\n * Verifies that the provided input is a valid AbortController\n */\nexport const isAbortController = (input: unknown): input is AbortController => {\n  if (\n    typeof input === \"object\" &&\n    input !== null &&\n    \"signal\" in input &&\n    typeof input.signal === \"object\" &&\n    input.signal !== null &&\n    \"aborted\" in input.signal &&\n    typeof input.signal.aborted === \"boolean\" &&\n    \"abort\" in input &&\n    typeof input.abort === \"function\"\n    // note, there are more things in this interface, but I stop the check here at `context.signal.aborted` and `context.abort` because (as off November 2022) that's all that connect-web is using (in `callback-client.ts`).\n  ) {\n    return true;\n  }\n  return false;\n};\n\n/**\n * @see `Updater` from `@tanstack/react-query`\n */\nexport type ConnectUpdater<O extends DescMessage> =\n  | MessageInitShape<O>\n  | undefined\n  | ((prev?: MessageShape<O>) => MessageShape<O> | undefined);\n\n/**\n * This helper makes sure that the type for the original response message is returned.\n *\n * @deprecated the ConnectQueryKey type now links to the return data type so `setQueryData` can be called safely without this helper.\n */\nexport const createProtobufSafeUpdater =\n  <O extends DescMessage>(\n    schema: Pick<DescMethodUnary<never, O>, \"output\">,\n    updater: ConnectUpdater<O>,\n  ) =>\n  (prev?: MessageShape<O>): MessageShape<O> | undefined => {\n    if (typeof updater !== \"function\") {\n      if (updater === undefined) {\n        return undefined;\n      }\n      if (isMessage(updater, schema.output)) {\n        return updater;\n      }\n      return create(schema.output, updater);\n    }\n    return updater(prev);\n  };\n"
  },
  {
    "path": "packages/connect-query-core/tsconfig.build.json",
    "content": "{\n  \"extends\": \"../../tsconfig.base.json\",\n  \"files\": [\"src/index.ts\"]\n}\n"
  },
  {
    "path": "packages/connect-query-core/tsconfig.json",
    "content": "{\n  \"include\": [\n    \"**/*.test.ts\",\n    \"**/*.test.tsx\",\n    \"src/test/**.tsx\",\n    \"vite.config.ts\"\n  ],\n  \"extends\": \"./tsconfig.build.json\"\n}\n"
  },
  {
    "path": "packages/connect-query-core/vite.config.ts",
    "content": "// Copyright 2021-2023 The Connect Authors\n//\n// Licensed under the Apache License, Version 2.0 (the \"License\");\n// you may not use this file except in compliance with the License.\n// You may obtain a copy of the License at\n//\n//      http://www.apache.org/licenses/LICENSE-2.0\n//\n// Unless required by applicable law or agreed to in writing, software\n// distributed under the License is distributed on an \"AS IS\" BASIS,\n// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n// See the License for the specific language governing permissions and\n// limitations under the License.\n\nimport { defineConfig } from \"vitest/config\";\n\n// https://vitejs.dev/config/\nexport default defineConfig({\n  test: {\n    environment: \"jsdom\",\n    typecheck: {\n      enabled: true,\n      // Modified to typecheck definition files as well as source files\n      include: [\"**/*.{test,spec}?(-d).?(c|m)[jt]s?(x)\"],\n    },\n    coverage: {\n      provider: \"istanbul\",\n      thresholds: {\n        branches: 100,\n        functions: 100,\n        lines: 100,\n        statements: 100,\n      },\n    },\n  },\n});\n"
  },
  {
    "path": "packages/examples/react/basic/.gitignore",
    "content": "# Logs\nlogs\n*.log\nnpm-debug.log*\npnpm-debug.log*\n\nnode_modules\ndist\ndist-ssr\n*.local\n\n# Editor directories and files\n.vscode/*\n!.vscode/extensions.json\n.idea\n.DS_Store\n*.suo\n*.ntvs*\n*.njsproj\n*.sln\n*.sw?\n"
  },
  {
    "path": "packages/examples/react/basic/buf.gen.yaml",
    "content": "# buf.gen.yaml defines a local generation template.\n# For details, see https://buf.build/docs/configuration/v2/buf-gen-yaml\nversion: v2\ninputs:\n  - proto_file: eliza.proto\n# Deletes the directories specified in the `out` field for all plugins before running code generation.\nclean: true\nplugins:\n  - local: protoc-gen-es\n    out: src/gen\n    opt:\n      - target=ts\n  - local: protoc-gen-connect-query\n    out: src/gen\n    opt:\n      - target=ts\n"
  },
  {
    "path": "packages/examples/react/basic/eliza.proto",
    "content": "// Copyright 2021-2023 The Connect Authors\n//\n// Licensed under the Apache License, Version 2.0 (the \"License\");\n// you may not use this file except in compliance with the License.\n// You may obtain a copy of the License at\n//\n//      http://www.apache.org/licenses/LICENSE-2.0\n//\n// Unless required by applicable law or agreed to in writing, software\n// distributed under the License is distributed on an \"AS IS\" BASIS,\n// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n// See the License for the specific language governing permissions and\n// limitations under the License.\n\nsyntax = \"proto3\";\n\npackage connectrpc.eliza.v1;\n\n// ElizaService provides a way to talk to Eliza, a port of the DOCTOR script\n// for Joseph Weizenbaum's original ELIZA program. Created in the mid-1960s at\n// the MIT Artificial Intelligence Laboratory, ELIZA demonstrates the\n// superficiality of human-computer communication. DOCTOR simulates a\n// psychotherapist, and is commonly found as an Easter egg in emacs\n// distributions.\nservice ElizaService {\n  // Say is a unary RPC. Eliza responds to the prompt with a single sentence.\n  rpc Say(SayRequest) returns (SayResponse) {}\n}\n\n// SayRequest is a single-sentence request.\nmessage SayRequest {\n  string sentence = 1;\n}\n\n// SayResponse is a single-sentence response.\nmessage SayResponse {\n  string sentence = 1;\n}\n"
  },
  {
    "path": "packages/examples/react/basic/index.html",
    "content": "<!doctype html>\n<html lang=\"en\">\n  <head>\n    <meta charset=\"UTF-8\" />\n    <link rel=\"icon\" type=\"image/svg+xml\" href=\"/vite.svg\" />\n    <meta name=\"viewport\" content=\"width=device-width, initial-scale=1.0\" />\n    <title>Vite + React + TS</title>\n  </head>\n  <body>\n    <div id=\"root\"></div>\n    <script type=\"module\" src=\"/src/main.tsx\"></script>\n  </body>\n</html>\n"
  },
  {
    "path": "packages/examples/react/basic/package.json",
    "content": "{\n  \"name\": \"@connectrpc/connect-query-example-basic\",\n  \"version\": \"2.2.0\",\n  \"private\": true,\n  \"type\": \"module\",\n  \"scripts\": {\n    \"dev\": \"vite\",\n    \"generate\": \"buf generate\",\n    \"license-header\": \"license-header\",\n    \"test\": \"vitest --run\",\n    \"test:watch\": \"vitest --watch --ui\",\n    \"lint\": \"eslint --max-warnings 0 .\",\n    \"format\": \"prettier --write . '!src/gen'\"\n  },\n  \"dependencies\": {\n    \"@bufbuild/buf\": \"1.54.0\",\n    \"@bufbuild/protobuf\": \"^2.5.1\",\n    \"@bufbuild/protoc-gen-es\": \"^2.5.1\",\n    \"@connectrpc/connect\": \"^2.0.2\",\n    \"@connectrpc/connect-query\": \"^2.2.0\",\n    \"@connectrpc/connect-web\": \"^2.0.2\",\n    \"@connectrpc/protoc-gen-connect-query\": \"^2.2.0\",\n    \"@tanstack/react-query\": \"^5.79.0\",\n    \"@tanstack/react-query-devtools\": \"^5.79.0\",\n    \"@testing-library/jest-dom\": \"^6.6.3\",\n    \"@testing-library/react\": \"^16.3.0\",\n    \"@types/react\": \"^19.1.6\",\n    \"@types/react-dom\": \"^19.1.5\",\n    \"@vitejs/plugin-react\": \"^4.5.0\",\n    \"react\": \"^19.1.0\",\n    \"react-dom\": \"^19.1.0\",\n    \"typescript\": \"^5.8.3\",\n    \"vite\": \"^6.3.5\"\n  }\n}\n"
  },
  {
    "path": "packages/examples/react/basic/src/css.ts",
    "content": "// Copyright 2021-2023 The Connect Authors\n//\n// Licensed under the Apache License, Version 2.0 (the \"License\");\n// you may not use this file except in compliance with the License.\n// You may obtain a copy of the License at\n//\n//      http://www.apache.org/licenses/LICENSE-2.0\n//\n// Unless required by applicable law or agreed to in writing, software\n// distributed under the License is distributed on an \"AS IS\" BASIS,\n// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n// See the License for the specific language governing permissions and\n// limitations under the License.\n\nexport const borderRadius = 6;\nexport const margin = 6;\nexport const padding = 6;\nexport const boxShadow = \"0px 1px 2px rgba(15, 16, 77, 0.05)\";\nexport const border = \"1px solid #E4E9EF\";\n\nexport const lightBlue = \"#C4E8FC\";\nexport const white = \"#FFFFFF\";\n"
  },
  {
    "path": "packages/examples/react/basic/src/datum.tsx",
    "content": "// Copyright 2021-2023 The Connect Authors\n//\n// Licensed under the Apache License, Version 2.0 (the \"License\");\n// you may not use this file except in compliance with the License.\n// You may obtain a copy of the License at\n//\n//      http://www.apache.org/licenses/LICENSE-2.0\n//\n// Unless required by applicable law or agreed to in writing, software\n// distributed under the License is distributed on an \"AS IS\" BASIS,\n// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n// See the License for the specific language governing permissions and\n// limitations under the License.\n\nimport { type FC, type ReactNode, useId } from \"react\";\n\nimport {\n  border,\n  borderRadius,\n  boxShadow,\n  lightBlue,\n  margin,\n  padding,\n  white,\n} from \"./css\";\n\ninterface DatumProps {\n  datum: string;\n  label: string;\n}\n\n/**\n * A single data point\n */\nexport const Datum: FC<DatumProps> = ({ datum, label }) => {\n  const id = useId();\n  return (\n    <div\n      style={{\n        borderRadius,\n        border,\n        margin,\n        overflow: \"hidden\",\n        zIndex: 1,\n        boxShadow,\n      }}\n    >\n      <label\n        style={{\n          padding: padding * 2,\n          backgroundColor: lightBlue,\n        }}\n        id={id}\n      >\n        {label}\n      </label>\n\n      <div\n        style={{\n          padding: padding * 2,\n          backgroundColor: white,\n        }}\n        aria-labelledby={id}\n      >\n        {datum}\n      </div>\n    </div>\n  );\n};\n\n/**\n * Wrapper Datum children\n */\nexport const Data: FC<{\n  children: ReactNode[];\n}> = ({ children }) => (\n  <div\n    style={{\n      display: \"flex\",\n      flexDirection: \"column\",\n      margin,\n    }}\n  >\n    {children}\n  </div>\n);\n"
  },
  {
    "path": "packages/examples/react/basic/src/example.tsx",
    "content": "// Copyright 2021-2023 The Connect Authors\n//\n// Licensed under the Apache License, Version 2.0 (the \"License\");\n// you may not use this file except in compliance with the License.\n// You may obtain a copy of the License at\n//\n//      http://www.apache.org/licenses/LICENSE-2.0\n//\n// Unless required by applicable law or agreed to in writing, software\n// distributed under the License is distributed on an \"AS IS\" BASIS,\n// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n// See the License for the specific language governing permissions and\n// limitations under the License.\n\nimport { useQuery } from \"@connectrpc/connect-query\";\nimport type { FC } from \"react\";\n\nimport { Data, Datum } from \"./datum\";\nimport { say } from \"./gen/eliza-ElizaService_connectquery\";\nimport { Indicator, Indicators } from \"./indicator\";\nimport { Page } from \"./page\";\n\n/**\n * This example demonstrates a basic usage of Connect-Query with `useQuery`\n */\nexport const Example: FC = () => {\n  const { status, fetchStatus, error, data } = useQuery(say, {\n    sentence: \"Hello\",\n  });\n\n  return (\n    <Page>\n      Status: {status}\n      <Indicators label=\"queryStatus\">\n        <Indicator label=\"pending\" parent={status} />\n        <Indicator label=\"success\" parent={status} />\n        <Indicator label=\"error\" parent={status} />\n      </Indicators>\n      <Indicators label=\"fetchStatus\">\n        <Indicator label=\"fetching\" parent={fetchStatus} />\n        <Indicator label=\"idle\" parent={fetchStatus} />\n        <Indicator label=\"paused\" parent={fetchStatus} />\n      </Indicators>\n      <Data>\n        <Datum label=\"data\" datum={JSON.stringify(data)} />\n        <Datum label=\"error\" datum={JSON.stringify(error)} />\n      </Data>\n    </Page>\n  );\n};\n"
  },
  {
    "path": "packages/examples/react/basic/src/gen/eliza-ElizaService_connectquery.ts",
    "content": "// Copyright 2021-2023 The Connect Authors\n//\n// Licensed under the Apache License, Version 2.0 (the \"License\");\n// you may not use this file except in compliance with the License.\n// You may obtain a copy of the License at\n//\n//      http://www.apache.org/licenses/LICENSE-2.0\n//\n// Unless required by applicable law or agreed to in writing, software\n// distributed under the License is distributed on an \"AS IS\" BASIS,\n// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n// See the License for the specific language governing permissions and\n// limitations under the License.\n\n// @generated by protoc-gen-connect-query v2.2.0 with parameter \"target=ts\"\n// @generated from file eliza.proto (package connectrpc.eliza.v1, syntax proto3)\n/* eslint-disable */\n\nimport { ElizaService } from \"./eliza_pb\";\n\n/**\n * Say is a unary RPC. Eliza responds to the prompt with a single sentence.\n *\n * @generated from rpc connectrpc.eliza.v1.ElizaService.Say\n */\nexport const say = ElizaService.method.say;\n"
  },
  {
    "path": "packages/examples/react/basic/src/gen/eliza_pb.ts",
    "content": "// Copyright 2021-2023 The Connect Authors\n//\n// Licensed under the Apache License, Version 2.0 (the \"License\");\n// you may not use this file except in compliance with the License.\n// You may obtain a copy of the License at\n//\n//      http://www.apache.org/licenses/LICENSE-2.0\n//\n// Unless required by applicable law or agreed to in writing, software\n// distributed under the License is distributed on an \"AS IS\" BASIS,\n// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n// See the License for the specific language governing permissions and\n// limitations under the License.\n\n// @generated by protoc-gen-es v2.6.2 with parameter \"target=ts\"\n// @generated from file eliza.proto (package connectrpc.eliza.v1, syntax proto3)\n/* eslint-disable */\n\nimport type { GenFile, GenMessage, GenService } from \"@bufbuild/protobuf/codegenv2\";\nimport { fileDesc, messageDesc, serviceDesc } from \"@bufbuild/protobuf/codegenv2\";\nimport type { Message } from \"@bufbuild/protobuf\";\n\n/**\n * Describes the file eliza.proto.\n */\nexport const file_eliza: GenFile = /*@__PURE__*/\n  fileDesc(\"CgtlbGl6YS5wcm90bxITY29ubmVjdHJwYy5lbGl6YS52MSIeCgpTYXlSZXF1ZXN0EhAKCHNlbnRlbmNlGAEgASgJIh8KC1NheVJlc3BvbnNlEhAKCHNlbnRlbmNlGAEgASgJMloKDEVsaXphU2VydmljZRJKCgNTYXkSHy5jb25uZWN0cnBjLmVsaXphLnYxLlNheVJlcXVlc3QaIC5jb25uZWN0cnBjLmVsaXphLnYxLlNheVJlc3BvbnNlIgBiBnByb3RvMw\");\n\n/**\n * SayRequest is a single-sentence request.\n *\n * @generated from message connectrpc.eliza.v1.SayRequest\n */\nexport type SayRequest = Message<\"connectrpc.eliza.v1.SayRequest\"> & {\n  /**\n   * @generated from field: string sentence = 1;\n   */\n  sentence: string;\n};\n\n/**\n * Describes the message connectrpc.eliza.v1.SayRequest.\n * Use `create(SayRequestSchema)` to create a new message.\n */\nexport const SayRequestSchema: GenMessage<SayRequest> = /*@__PURE__*/\n  messageDesc(file_eliza, 0);\n\n/**\n * SayResponse is a single-sentence response.\n *\n * @generated from message connectrpc.eliza.v1.SayResponse\n */\nexport type SayResponse = Message<\"connectrpc.eliza.v1.SayResponse\"> & {\n  /**\n   * @generated from field: string sentence = 1;\n   */\n  sentence: string;\n};\n\n/**\n * Describes the message connectrpc.eliza.v1.SayResponse.\n * Use `create(SayResponseSchema)` to create a new message.\n */\nexport const SayResponseSchema: GenMessage<SayResponse> = /*@__PURE__*/\n  messageDesc(file_eliza, 1);\n\n/**\n * ElizaService provides a way to talk to Eliza, a port of the DOCTOR script\n * for Joseph Weizenbaum's original ELIZA program. Created in the mid-1960s at\n * the MIT Artificial Intelligence Laboratory, ELIZA demonstrates the\n * superficiality of human-computer communication. DOCTOR simulates a\n * psychotherapist, and is commonly found as an Easter egg in emacs\n * distributions.\n *\n * @generated from service connectrpc.eliza.v1.ElizaService\n */\nexport const ElizaService: GenService<{\n  /**\n   * Say is a unary RPC. Eliza responds to the prompt with a single sentence.\n   *\n   * @generated from rpc connectrpc.eliza.v1.ElizaService.Say\n   */\n  say: {\n    methodKind: \"unary\";\n    input: typeof SayRequestSchema;\n    output: typeof SayResponseSchema;\n  },\n}> = /*@__PURE__*/\n  serviceDesc(file_eliza, 0);\n\n"
  },
  {
    "path": "packages/examples/react/basic/src/index.css",
    "content": ":root {\n  font-family: Inter, Helvetica, Arial, sans-serif;\n  font-size: 16px;\n  line-height: 24px;\n  font-weight: 400;\n  background-color: #f5f7fa;\n}\n\nbody {\n  margin: 0;\n  display: flex;\n}\n"
  },
  {
    "path": "packages/examples/react/basic/src/indicator.tsx",
    "content": "// Copyright 2021-2023 The Connect Authors\n//\n// Licensed under the Apache License, Version 2.0 (the \"License\");\n// you may not use this file except in compliance with the License.\n// You may obtain a copy of the License at\n//\n//      http://www.apache.org/licenses/LICENSE-2.0\n//\n// Unless required by applicable law or agreed to in writing, software\n// distributed under the License is distributed on an \"AS IS\" BASIS,\n// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n// See the License for the specific language governing permissions and\n// limitations under the License.\n\nimport type { FC, ReactNode } from \"react\";\n\nimport { border, borderRadius, boxShadow, margin } from \"./css\";\n\n/**\n * a single Indicator\n */\nexport const Indicator = <T extends string, U extends T>({\n  label,\n  parent,\n}: {\n  label: U;\n  parent: T;\n}) => {\n  const height = \"50px\";\n  const active = label === parent;\n\n  return (\n    <div\n      style={{\n        width: 100,\n        height,\n        border,\n        borderRadius,\n        backgroundColor: active ? \"#C4E8FC\" : \"#FFFFFF\",\n        boxShadow,\n        margin,\n        textAlign: \"center\",\n        lineHeight: height,\n      }}\n    >\n      {label}\n    </div>\n  );\n};\n\n/**\n * A wrapper for `Indicator`s\n */\nexport const Indicators: FC<{\n  children: ReactNode;\n  label: string;\n}> = ({ children, label }) => {\n  return (\n    <div\n      style={{\n        display: \"flex\",\n        flexDirection: \"column\",\n        margin,\n      }}\n    >\n      <div\n        style={{\n          textAlign: \"center\",\n        }}\n      >\n        {label}\n      </div>\n      {children}\n    </div>\n  );\n};\n"
  },
  {
    "path": "packages/examples/react/basic/src/main.test.tsx",
    "content": "// Copyright 2021-2023 The Connect Authors\n//\n// Licensed under the Apache License, Version 2.0 (the \"License\");\n// you may not use this file except in compliance with the License.\n// You may obtain a copy of the License at\n//\n//      http://www.apache.org/licenses/LICENSE-2.0\n//\n// Unless required by applicable law or agreed to in writing, software\n// distributed under the License is distributed on an \"AS IS\" BASIS,\n// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n// See the License for the specific language governing permissions and\n// limitations under the License.\n\nimport \"@testing-library/jest-dom/vitest\";\n\nimport { createRouterTransport } from \"@connectrpc/connect\";\nimport { render, screen } from \"@testing-library/react\";\nimport { describe, expect, it } from \"vitest\";\n\nimport * as methods from \"./gen/eliza-ElizaService_connectquery\";\nimport Main from \"./main\";\n\ndescribe(\"Application\", () => {\n  it(\"should show success status and response data\", async () => {\n    const transport = createRouterTransport(({ rpc }) => {\n      rpc(methods.say, () => ({\n        sentence: \"Hello, world!\",\n      }));\n    });\n    render(<Main transport={transport} />);\n    const text = await screen.findByText(\"Status: success\");\n    expect(text).toBeInTheDocument();\n    const response = await screen.findByLabelText(\"data\");\n    expect(response).toHaveTextContent(\n      '{\"$typeName\":\"connectrpc.eliza.v1.SayResponse\",\"sentence\":\"Hello, world!\"}',\n    );\n  });\n});\n"
  },
  {
    "path": "packages/examples/react/basic/src/main.tsx",
    "content": "// Copyright 2021-2023 The Connect Authors\n//\n// Licensed under the Apache License, Version 2.0 (the \"License\");\n// you may not use this file except in compliance with the License.\n// You may obtain a copy of the License at\n//\n//      http://www.apache.org/licenses/LICENSE-2.0\n//\n// Unless required by applicable law or agreed to in writing, software\n// distributed under the License is distributed on an \"AS IS\" BASIS,\n// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n// See the License for the specific language governing permissions and\n// limitations under the License.\n\nimport \"./index.css\";\n\nimport type { Transport } from \"@connectrpc/connect\";\nimport { TransportProvider } from \"@connectrpc/connect-query\";\nimport { createConnectTransport } from \"@connectrpc/connect-web\";\nimport { QueryClient, QueryClientProvider } from \"@tanstack/react-query\";\nimport { ReactQueryDevtools } from \"@tanstack/react-query-devtools\";\nimport * as ReactDOM from \"react-dom/client\";\n\nimport { Example } from \"./example\";\n\nconst queryClient = new QueryClient();\n\n/**\n * The application root\n */\nexport default function App({ transport }: { transport?: Transport }) {\n  const finalTransport =\n    transport ??\n    createConnectTransport({\n      baseUrl: \"https://demo.connectrpc.com\",\n    });\n  return (\n    <TransportProvider transport={finalTransport}>\n      <QueryClientProvider client={queryClient}>\n        <Example />\n        <ReactQueryDevtools initialIsOpen />\n      </QueryClientProvider>\n    </TransportProvider>\n  );\n}\n\nconst rootElement = document.getElementById(\"root\");\nif (rootElement) {\n  ReactDOM.createRoot(rootElement).render(<App />);\n}\n"
  },
  {
    "path": "packages/examples/react/basic/src/page.tsx",
    "content": "// Copyright 2021-2023 The Connect Authors\n//\n// Licensed under the Apache License, Version 2.0 (the \"License\");\n// you may not use this file except in compliance with the License.\n// You may obtain a copy of the License at\n//\n//      http://www.apache.org/licenses/LICENSE-2.0\n//\n// Unless required by applicable law or agreed to in writing, software\n// distributed under the License is distributed on an \"AS IS\" BASIS,\n// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n// See the License for the specific language governing permissions and\n// limitations under the License.\n\nimport type { FC, PropsWithChildren } from \"react\";\n\nimport { margin } from \"./css\";\n\n/**\n * The wrapper for the whole page\n */\nexport const Page: FC<PropsWithChildren> = ({ children }) => (\n  <div\n    style={{\n      margin: margin * 3,\n      maxWidth: 800,\n      display: \"flex\",\n    }}\n  >\n    {children}\n  </div>\n);\n"
  },
  {
    "path": "packages/examples/react/basic/src/vite-env.d.ts",
    "content": "// Copyright 2021-2023 The Connect Authors\n//\n// Licensed under the Apache License, Version 2.0 (the \"License\");\n// you may not use this file except in compliance with the License.\n// You may obtain a copy of the License at\n//\n//      http://www.apache.org/licenses/LICENSE-2.0\n//\n// Unless required by applicable law or agreed to in writing, software\n// distributed under the License is distributed on an \"AS IS\" BASIS,\n// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n// See the License for the specific language governing permissions and\n// limitations under the License.\n\n/// <reference types=\"vite/client\" />\n"
  },
  {
    "path": "packages/examples/react/basic/tsconfig.json",
    "content": "{\n  \"compilerOptions\": {\n    \"allowJs\": false,\n    \"allowSyntheticDefaultImports\": true,\n    \"esModuleInterop\": false,\n    \"exactOptionalPropertyTypes\": true,\n    \"forceConsistentCasingInFileNames\": true,\n    \"isolatedModules\": true,\n    \"jsx\": \"react-jsx\",\n    \"lib\": [\"DOM\", \"DOM.Iterable\", \"ESNext\"],\n    \"module\": \"ESNext\",\n    \"moduleResolution\": \"Node\",\n    \"noEmit\": true,\n    \"resolveJsonModule\": true,\n    \"skipLibCheck\": true,\n    \"strict\": true,\n    \"target\": \"ESNext\",\n    \"useDefineForClassFields\": true,\n    \"types\": [\"node\"],\n    \"declaration\": true // necessary to check if generated code can be published\n  },\n  \"include\": [\"src\", \"./*.config.ts\", \"__mocks__\"]\n}\n"
  },
  {
    "path": "packages/examples/react/basic/vite.config.ts",
    "content": "// Copyright 2021-2023 The Connect Authors\n//\n// Licensed under the Apache License, Version 2.0 (the \"License\");\n// you may not use this file except in compliance with the License.\n// You may obtain a copy of the License at\n//\n//      http://www.apache.org/licenses/LICENSE-2.0\n//\n// Unless required by applicable law or agreed to in writing, software\n// distributed under the License is distributed on an \"AS IS\" BASIS,\n// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n// See the License for the specific language governing permissions and\n// limitations under the License.\n\nimport react from \"@vitejs/plugin-react\";\nimport { defineConfig } from \"vitest/config\";\n\n// https://vitejs.dev/config/\nexport default defineConfig({\n  plugins: [react()],\n  test: {\n    environment: \"jsdom\",\n    typecheck: {\n      enabled: true,\n      // Modified to typecheck definition files as well as source files\n      include: [\"**/*.{test,spec}?(-d).?(c|m)[jt]s?(x)\"],\n    },\n  },\n});\n"
  },
  {
    "path": "packages/protoc-gen-connect-query/.eslintignore",
    "content": "snapshots\n.type-dump\n"
  },
  {
    "path": "packages/protoc-gen-connect-query/.gitignore",
    "content": "# A directory that exists solely to hold the result of tsc since --noEmit doesn't discover to protability issue found\n# by https://github.com/connectrpc/connect-query-es/issues/209\n.type-dump"
  },
  {
    "path": "packages/protoc-gen-connect-query/README.md",
    "content": "# @connectrpc/protoc-gen-connect-query\n\n- [@connectrpc/protoc-gen-connect-query](#connectrpcprotoc-gen-connect-query)\n  - [Installation](#installation)\n  - [Generating Code](#generating-code)\n    - [`example.proto`](#exampleproto)\n    - [`buf.gen.yaml`](#bufgenyaml)\n    - [With the `buf` CLI](#with-the-buf-cli)\n    - [With `protoc`](#with-protoc)\n    - [With Node](#with-node)\n  - [Generated Output](#generated-output)\n  - [Plugin options](#plugin-options)\n    - [`target`](#target)\n    - [`import_extension`](#import_extension)\n    - [`keep_empty_files=true`](#keep_empty_filestrue)\n    - [`js_import_style`](#js_import_style)\n    - [`ts_nocheck=true`](#ts_nochecktrue)\n  - [Example Generated Code](#example-generated-code)\n\nThe code generator for Connect-Query, a expansion pack for [TanStack Query](https://tanstack.com/query) (react-query), that enables effortless communication with servers that speak the [Connect Protocol](https://connectrpc.com/docs/protocol).\n\nLearn more about Connect-Query at [github.com/connectrpc/connect-query-es](https://github.com/connectrpc/connect-query-es).\n\n## Installation\n\n`protoc-gen-connect-query` is a code generator plugin for Protocol Buffer compilers like [buf](https://github.com/bufbuild/buf) and [protoc](https://github.com/protocolbuffers/protobuf/releases). It generates clients from your Protocol Buffer schema, and works in tandem with\n[@bufbuild/protoc-gen-es](https://www.npmjs.com/package/@bufbuild/protoc-gen-es), the code generator plugin for all Protocol Buffer base types. The code those two plugins generate requires the runtime libraries [@connectrpc/connect-query](https://www.npmjs.com/package/@connectrpc/connect-query), and [@bufbuild/protobuf](https://www.npmjs.com/package/@bufbuild/protobuf).\n\nTo install the plugins and their runtime libraries, run:\n\n```shell\nnpm install --save-dev @connectrpc/protoc-gen-connect-query @bufbuild/protoc-gen-es\nnpm install @connectrpc/connect-query @bufbuild/protobuf\n```\n\nWe use peer dependencies to ensure that code generator and runtime library are compatible with each other. Note that yarn and pnpm only emit a warning in this case.\n\n## Generating Code\n\n### `example.proto`\n\nFor these examples, consider the following example proto file `example.proto`:\n\n```protobuf\nsyntax = \"proto3\";\n\npackage example.v1;\n\nmessage Nothing {}\n\nmessage Todo {\n  string id = 1;\n  string name = 2;\n  bool completed = 3;\n}\n\nmessage Todos {\n  repeated Todo todos = 1;\n}\n\nservice TodoService {\n  rpc GetTodos(Nothing) returns (Todos);\n  rpc AddTodo(Todo) returns (Nothing);\n}\n```\n\nThis file creates an RPC service with the following:\n\n- `GetTodos` takes no inputs and returns an array of `Todo`s.\n- `AddTodo` adds a new `Todo` and returns nothing.\n\n### `buf.gen.yaml`\n\nAdd a new configuration file `buf.gen.yaml`\n\n```yaml\nversion: v2\nplugins:\n  # This will invoke protoc-gen-es and write output to src/gen\n  - local: protoc-gen-es\n    out: src/gen\n    opt: target=ts\n    # This will invoke protoc-gen-connect-query\n  - local: protoc-gen-connect-query\n    out: src/gen\n    opt: target=ts\n```\n\n### With the `buf` CLI\n\nTo use the [buf CLI](https://docs.buf.build/generate/usage#generate-code-using-local-plugins) to generate code for all protobuf files within your project, simply run:\n\n```bash\nnpx @bufbuild/buf generate\n```\n\n> Note that `buf` can generate from various [inputs](https://docs.buf.build/reference/inputs), not just local protobuf files. For example, `npm run generate buf.build/connectrpc/eliza` generates code for the module [connectrpc/eliza](https://buf.build/connectrpc/eliza) on the Buf Schema Registry.\n\n### With `protoc`\n\n```bash\nPATH=$PATH:$(pwd)/node_modules/.bin \\\n  protoc -I . \\\n  --es_out src/gen \\\n  --es_opt target=ts \\\n  --connect-query_out src/gen \\\n  --connect-query_opt target=ts \\\n  example.proto\n```\n\nNote that we are adding `node_modules/.bin` to the `$PATH`, so that the protocol buffer compiler can find them. This happens automatically with npm scripts.\n\n> Note: Since yarn v2 and above does not use a `node_modules` directory, you need to change the variable a bit:\n>\n> ```bash\n> PATH=$(dirname $(yarn bin protoc-gen-es)):$(dirname $(yarn bin protoc-gen-connect-es)):$PATH\n> ```\n\n### With Node\n\nAdd a line to the `scripts` section of your `package.json` to run `buf generate`.\n\n```json\n\"scripts\": {\n    ...\n    \"buf:generate\": \"buf generate\"\n},\n```\n\nFinally, tell Buf to generate code by running your command:\n\n```bash\nnpm run buf:generate\n```\n\nNow you should see your generated code:\n\n```tree\n.\n└── gen/\n    ├── example_pb.ts\n    └── example-TodoService_connectquery.ts\n```\n\n## Generated Output\n\nConnect-Query will create one output file for every service in every protofile. Say you have the following file structure:\n\n```tree\n.\n└── proto/\n    ├── pizza.proto\n    └── curry.proto\n```\n\nWhere `pizza.proto` contains `DetroitStyleService` and `ChicagoStyleService`, and where `curry.proto` contains `VindalooService`. Your generated output will look like this:\n\n```tree\n.\n└── gen/\n    ├── pizza_pb.ts\n    ├── pizza-DetroitStyleService_connectquery.ts\n    ├── pizza-ChicagoStyleService_connectquery.ts\n    ├── curry_pb.ts\n    └── curry-VindalooService_connectquery.ts\n```\n\nThe reason each service gets a separate file is to facilitate intellisense and [language server protocol imports](https://github.com/typescript-language-server/typescript-language-server#organize-imports). Notice that one file per input proto is generated by `protoc-gen-es` (`pizza_pb.ts` and `curry_pb.ts`), and that one file per service is created by `protoc-gen-connect-query` (making up the remainder). The Protobuf-ES generated files (`*_pb.ts`) are important because those files are referenced from the `*_connectquery.ts` files.\n\n## Plugin options\n\n### `target`\n\nThis option controls whether the plugin generates JavaScript, TypeScript, or TypeScript declaration files.\n\nSay, for example, you used [`example.proto`](#exampleproto):\n\n| Target       | Generated output                        |\n| ------------ | --------------------------------------- |\n| `target=js`  | `example-TodoService_connectquery.js`   |\n| `target=ts`  | `example-TodoService_connectquery.ts`   |\n| `target=dts` | `example-TodoService_connectquery.d.ts` |\n\nMultiple values can be given by separating them with `+`, for example `target=js+dts`.\n\nBy default, we generate JavaScript and TypeScript declaration files, which produces the smallest code size and is the most compatible with various bundler configurations. If you prefer to generate TypeScript, use `target=ts`.\n\n### `import_extension`\n\nBy default, [protoc-gen-connect-query](https://www.npmjs.com/package/@connectrpc/protoc-gen-connect-query) (and all other plugins based on [@bufbuild/protoplugin](https://www.npmjs.com/package/@bufbuild/protoplugin)) doesn't add file extensions to import paths. However, some environments require an import extension. For example, using ECMAScript modules in Node.js requires the `.js` extension, and Deno requires `.ts`. With this plugin option, you can add `.js`/`.ts` extensions in import paths with the given value. Possible values:\n\n- `import_extension=none`: Doesn't add an extension. (Default)\n- `import_extension=js`: Adds the `.js` extension.\n- `import_extension=ts`. Adds the `.ts` extension.\n\n### `js_import_style`\n\nBy default, [protoc-gen-connect-query](https://www.npmjs.com/package/@connectrpc/protoc-gen-connect-query)\n(and all other plugins based on [@bufbuild/protoplugin](https://www.npmjs.com/package/@bufbuild/protoplugin))\ngenerate ECMAScript `import` and `export` statements. For use cases where\nCommonJS is difficult to avoid, this option can be used to generate CommonJS\n`require()` calls.\n\nPossible values:\n\n- `js_import_style=module` generate ECMAScript `import` / `export` statements -\n  the default behavior.\n- `js_import_style=legacy_commonjs` generate CommonJS `require()` calls.\n\n### `keep_empty_files=true`\n\nThis option exists for other plugins but is not applicable to `protoc-gen-connect-query` because, unlike most other plugins, it does not generate a maximum of one output file for every input proto file. Instead, it generates one output file per service. If you provide a valid proto file that contains no services, `protoc-gen-connect-query` will have no output.\n\n### `ts_nocheck=true`\n\n[protoc-gen-connect-query](https://www.npmjs.com/package/@connectrpc/protoc-gen-connect-query) generates valid TypeScript for current versions of the TypeScript compiler with standard settings. If you use compiler settings that yield an error for generated code, setting this option generates an annotation at the top of each file to skip type checks: `// @ts-nocheck`.\n\n## Example Generated Code\n\nSee [`eliza.proto`](../examples/react/basic/eliza.proto) for example inputs, and look [here](../examples/react/basic/src/gen) to see the outputs those files generate.\n"
  },
  {
    "path": "packages/protoc-gen-connect-query/bin/protoc-gen-connect-query",
    "content": "#!/usr/bin/env node\n\nconst { runNodeJs } = require(\"@bufbuild/protoplugin\");\nconst {\n  protocGenConnectQuery,\n} = require(\"../dist/cjs/src/protoc-gen-connect-query-plugin.js\");\n\nrunNodeJs(protocGenConnectQuery);\n"
  },
  {
    "path": "packages/protoc-gen-connect-query/package.json",
    "content": "{\n  \"name\": \"@connectrpc/protoc-gen-connect-query\",\n  \"version\": \"2.2.0\",\n  \"description\": \"Code generator for connect-query\",\n  \"license\": \"Apache-2.0\",\n  \"sideEffects\": false,\n  \"repository\": {\n    \"type\": \"git\",\n    \"url\": \"https://github.com/connectrpc/connect-query-es.git\",\n    \"directory\": \"packages/protoc-gen-connect-query\"\n  },\n  \"files\": [\n    \"dist/**\"\n  ],\n  \"bin\": {\n    \"protoc-gen-connect-query\": \"bin/protoc-gen-connect-query\"\n  },\n  \"engines\": {\n    \"node\": \">=20\"\n  },\n  \"scripts\": {\n    \"prebuild\": \"rm -rf ./dist/*\",\n    \"build\": \"tsc --project tsconfig.json --module commonjs --verbatimModuleSyntax false --moduleResolution node10 --outDir ./dist/cjs\",\n    \"format\": \"prettier --write --ignore-unknown '.' '!dist'\",\n    \"license-header\": \"license-header\",\n    \"lint\": \"eslint --max-warnings 0 .\"\n  },\n  \"preferUnplugged\": true,\n  \"devDependencies\": {\n    \"@bufbuild/buf\": \"1.54.0\",\n    \"@bufbuild/protoc-gen-es\": \"^2.5.1\",\n    \"@connectrpc/connect\": \"^2.0.2\",\n    \"@connectrpc/connect-query\": \"^2.2.0\",\n    \"@tanstack/react-query\": \"^5.79.0\",\n    \"typescript\": \"^5.8.3\"\n  },\n  \"dependencies\": {\n    \"@bufbuild/protobuf\": \"^2.5.1\",\n    \"@bufbuild/protoplugin\": \"^2.2.1\"\n  },\n  \"peerDependencies\": {\n    \"@bufbuild/protoc-gen-es\": \"2.x\"\n  },\n  \"peerDependenciesMeta\": {\n    \"@bufbuild/protoc-gen-es\": {\n      \"optional\": true\n    }\n  }\n}\n"
  },
  {
    "path": "packages/protoc-gen-connect-query/src/generateDts.ts",
    "content": "// Copyright 2021-2023 The Connect Authors\n//\n// Licensed under the Apache License, Version 2.0 (the \"License\");\n// you may not use this file except in compliance with the License.\n// You may obtain a copy of the License at\n//\n//      http://www.apache.org/licenses/LICENSE-2.0\n//\n// Unless required by applicable law or agreed to in writing, software\n// distributed under the License is distributed on an \"AS IS\" BASIS,\n// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n// See the License for the specific language governing permissions and\n// limitations under the License.\n\nimport type { DescFile, DescService } from \"@bufbuild/protobuf\";\nimport type { Schema } from \"@bufbuild/protoplugin\";\nimport { safeIdentifier } from \"@bufbuild/protoplugin\";\n\nimport type { PluginInit } from \"./utils.js\";\n\n// prettier-ignore\n/**\n * Handles generating a TypeScript Declaration file for a given Schema, DescFile (protobuf definition) and protobuf Service.\n */\nconst generateServiceFile =\n  (schema: Schema, protoFile: DescFile) => (service: DescService) => {\n\n    const f = schema.generateFile(\n      `${protoFile.name}-${service.name}_connectquery.d.ts`,\n    );\n\n    f.preamble(protoFile);\n\n    service.methods.forEach((method) => {\n      switch (method.methodKind) {\n        case \"unary\":\n          {\n            f.print(f.jsDoc(method));\n            f.print(f.export(\"const\", safeIdentifier(method.localName)), \": typeof \", f.importSchema(service), '[\"method\"][\"', method.localName, '\"];');\n          }\n          break;\n\n        default:\n          return;\n      }\n    });\n  };\n\n/**\n * This function generates the TypeScript Definition output files\n */\nexport const generateDts: PluginInit[\"generateDts\"] = (schema) => {\n  schema.files.forEach((protoFile) => {\n    protoFile.services.forEach(generateServiceFile(schema, protoFile));\n  });\n};\n"
  },
  {
    "path": "packages/protoc-gen-connect-query/src/generateTs.ts",
    "content": "// Copyright 2021-2023 The Connect Authors\n//\n// Licensed under the Apache License, Version 2.0 (the \"License\");\n// you may not use this file except in compliance with the License.\n// You may obtain a copy of the License at\n//\n//      http://www.apache.org/licenses/LICENSE-2.0\n//\n// Unless required by applicable law or agreed to in writing, software\n// distributed under the License is distributed on an \"AS IS\" BASIS,\n// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n// See the License for the specific language governing permissions and\n// limitations under the License.\n\nimport type { DescFile, DescService } from \"@bufbuild/protobuf\";\nimport type { Schema } from \"@bufbuild/protoplugin\";\nimport { safeIdentifier } from \"@bufbuild/protoplugin\";\n\nimport type { PluginInit } from \"./utils.js\";\n\n// prettier-ignore\n/**\n * Handles generating a source code file for a given Schema, DescFile (protobuf definition) and protobuf Service.\n *\n * By pure luck, this file happens to be completely valid JavaScript since all the types are inferred.\n */\nconst generateServiceFile =\n  (schema: Schema, protoFile: DescFile, extension: 'js' | 'ts') =>\n    (service: DescService) => {\n    const f = schema.generateFile(\n      `${protoFile.name}-${service.name}_connectquery.${extension}`,\n    );\n    f.preamble(protoFile);\n\n    service.methods\n      .filter((method) => method.methodKind === \"unary\")\n      .forEach((method, index, filteredMethods) => {\n        f.print(f.jsDoc(method));\n        f.print(f.export(\"const\", safeIdentifier(method.localName)), \" = \", f.importSchema(service), \".method.\", method.localName, \";\");\n        const lastIndex = index === filteredMethods.length - 1;\n        if (!lastIndex) {\n          f.print();\n        }\n      });\n  };\n\n/**\n * This function generates the TypeScript output files\n */\nexport const generateTs: PluginInit[\"generateJs\"] & PluginInit[\"generateTs\"] = (\n  schema,\n  extension,\n) => {\n  schema.files.forEach((protoFile) => {\n    protoFile.services.forEach(\n      generateServiceFile(schema, protoFile, extension),\n    );\n  });\n};\n"
  },
  {
    "path": "packages/protoc-gen-connect-query/src/protoc-gen-connect-query-plugin.ts",
    "content": "// Copyright 2021-2023 The Connect Authors\n//\n// Licensed under the Apache License, Version 2.0 (the \"License\");\n// you may not use this file except in compliance with the License.\n// You may obtain a copy of the License at\n//\n//      http://www.apache.org/licenses/LICENSE-2.0\n//\n// Unless required by applicable law or agreed to in writing, software\n// distributed under the License is distributed on an \"AS IS\" BASIS,\n// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n// See the License for the specific language governing permissions and\n// limitations under the License.\n\nimport { createEcmaScriptPlugin } from \"@bufbuild/protoplugin\";\n\nimport { version } from \"../package.json\";\nimport { generateDts } from \"./generateDts.js\";\nimport { generateTs } from \"./generateTs.js\";\n\nexport const protocGenConnectQuery = createEcmaScriptPlugin({\n  name: \"protoc-gen-connect-query\",\n  version: `v${String(version)}`,\n  generateTs,\n\n  // The generated TypeScript output is completely valid JavaScript since all the types are inferred\n  generateJs: generateTs,\n  generateDts,\n});\n"
  },
  {
    "path": "packages/protoc-gen-connect-query/src/utils.ts",
    "content": "// Copyright 2021-2023 The Connect Authors\n//\n// Licensed under the Apache License, Version 2.0 (the \"License\");\n// you may not use this file except in compliance with the License.\n// You may obtain a copy of the License at\n//\n//      http://www.apache.org/licenses/LICENSE-2.0\n//\n// Unless required by applicable law or agreed to in writing, software\n// distributed under the License is distributed on an \"AS IS\" BASIS,\n// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n// See the License for the specific language governing permissions and\n// limitations under the License.\n\nimport type { createEcmaScriptPlugin } from \"@bufbuild/protoplugin\";\n\n/**\n * Extracts the type of PluginInit from @bufbuild/protoplugin\n */\nexport type PluginInit = Required<Parameters<typeof createEcmaScriptPlugin>[0]>;\n"
  },
  {
    "path": "packages/protoc-gen-connect-query/tsconfig.json",
    "content": "{\n  \"files\": [\"src/protoc-gen-connect-query-plugin.ts\"],\n  \"extends\": \"../../tsconfig.base.json\",\n  \"compilerOptions\": {\n    // We import the plugin's version number from package.json\n    \"resolveJsonModule\": true,\n    // This package is CommonJS\n    \"verbatimModuleSyntax\": false,\n    \"module\": \"CommonJS\",\n    \"moduleResolution\": \"Node10\"\n  }\n}\n"
  },
  {
    "path": "packages/test-utils/buf.gen.yaml",
    "content": "# buf.gen.yaml defines a local generation template.\n# For details, see https://buf.build/docs/configuration/v2/buf-gen-yaml\nversion: v2\ninputs:\n  - directory: proto\n# Deletes the directories specified in the `out` field for all plugins before running code generation.\nclean: true\nplugins:\n  - local: protoc-gen-es\n    out: src/gen\n    opt:\n      - target=ts\n"
  },
  {
    "path": "packages/test-utils/package.json",
    "content": "{\n  \"name\": \"test-utils\",\n  \"private\": true,\n  \"version\": \"2.2.0\",\n  \"type\": \"module\",\n  \"scripts\": {\n    \"generate\": \"buf generate\",\n    \"postgenerate\": \"license-header gen\",\n    \"prebuild\": \"rm -rf ./dist/*\",\n    \"build\": \"npm run build:cjs && npm run build:esm\",\n    \"build:cjs\": \"tsc --project tsconfig.json --module commonjs --verbatimModuleSyntax false --moduleResolution node10 --outDir ./dist/cjs --declaration --declarationDir ./dist/cjs && echo >./dist/cjs/package.json '{\\\"type\\\":\\\"commonjs\\\"}'\",\n    \"build:esm\": \"tsc --project tsconfig.json --outDir ./dist/esm --declaration --declarationDir ./dist/esm\",\n    \"format\": \"prettier --write --ignore-unknown '.' '!dist' '!src/gen'\",\n    \"license-header\": \"license-header --ignore 'src/gen/**'\",\n    \"lint\": \"eslint --max-warnings 0 .\"\n  },\n  \"main\": \"./dist/cjs/index.js\",\n  \"types\": \"./dist/cjs/index.d.ts\",\n  \"exports\": {\n    \".\": {\n      \"import\": \"./dist/esm/index.js\"\n    },\n    \"./gen/*\": {\n      \"import\": \"./dist/esm/gen/*\"\n    }\n  },\n  \"devDependencies\": {\n    \"@bufbuild/buf\": \"^1.54.0\",\n    \"@bufbuild/protobuf\": \"^2.5.1\",\n    \"@bufbuild/protoc-gen-es\": \"^2.5.1\",\n    \"@connectrpc/connect\": \"^2.0.2\",\n    \"@connectrpc/connect-web\": \"^2.0.2\",\n    \"@types/react\": \"^19.1.6\",\n    \"react\": \"^19.1.0\"\n  },\n  \"files\": [\n    \"dist/**\"\n  ]\n}\n"
  },
  {
    "path": "packages/test-utils/proto/bigint.proto",
    "content": "// Copyright 2021-2023 The Connect Authors\n//\n// Licensed under the Apache License, Version 2.0 (the \"License\");\n// you may not use this file except in compliance with the License.\n// You may obtain a copy of the License at\n//\n//      http://www.apache.org/licenses/LICENSE-2.0\n//\n// Unless required by applicable law or agreed to in writing, software\n// distributed under the License is distributed on an \"AS IS\" BASIS,\n// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n// See the License for the specific language governing permissions and\n// limitations under the License.\n\nsyntax = \"proto3\";\n\nimport \"google/protobuf/empty.proto\";\n\nservice BigIntService {\n  rpc Count(CountRequest) returns (CountResponse);\n  rpc GetCount(google.protobuf.Empty) returns (CountResponse);\n}\n\nmessage CountRequest {\n  int64 add = 1;\n}\n\nmessage CountResponse {\n  int64 count = 1;\n}\n"
  },
  {
    "path": "packages/test-utils/proto/eliza.proto",
    "content": "// Copyright 2021-2023 The Connect Authors\n//\n// Licensed under the Apache License, Version 2.0 (the \"License\");\n// you may not use this file except in compliance with the License.\n// You may obtain a copy of the License at\n//\n//      http://www.apache.org/licenses/LICENSE-2.0\n//\n// Unless required by applicable law or agreed to in writing, software\n// distributed under the License is distributed on an \"AS IS\" BASIS,\n// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n// See the License for the specific language governing permissions and\n// limitations under the License.\n\nsyntax = \"proto3\";\n\npackage connectrpc.eliza.v1;\n\n// ElizaService provides a way to talk to Eliza, a port of the DOCTOR script\n// for Joseph Weizenbaum's original ELIZA program. Created in the mid-1960s at\n// the MIT Artificial Intelligence Laboratory, ELIZA demonstrates the\n// superficiality of human-computer communication. DOCTOR simulates a\n// psychotherapist, and is commonly found as an Easter egg in emacs\n// distributions.\nservice ElizaService {\n  // Say is a unary RPC. Eliza responds to the prompt with a single sentence.\n  rpc Say(SayRequest) returns (SayResponse) {}\n}\n\n// SayRequest is a single-sentence request.\nmessage SayRequest {\n  string sentence = 1;\n}\n\n// SayResponse is a single-sentence response.\nmessage SayResponse {\n  string sentence = 1;\n}\n"
  },
  {
    "path": "packages/test-utils/proto/list.proto",
    "content": "// Copyright 2021-2023 The Connect Authors\n//\n// Licensed under the Apache License, Version 2.0 (the \"License\");\n// you may not use this file except in compliance with the License.\n// You may obtain a copy of the License at\n//\n//      http://www.apache.org/licenses/LICENSE-2.0\n//\n// Unless required by applicable law or agreed to in writing, software\n// distributed under the License is distributed on an \"AS IS\" BASIS,\n// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n// See the License for the specific language governing permissions and\n// limitations under the License.\n\nsyntax = \"proto3\";\n\nservice ListService {\n  rpc List(ListRequest) returns (ListResponse);\n  rpc NestedList(NestedListRequest) returns (NestedListResponse);\n}\n\nmessage ListRequest {\n  int64 page = 1;\n  bool preview = 2;\n}\n\nmessage ListResponse {\n  int64 page = 1;\n  repeated string items = 2;\n}\n\nmessage NestedListRequest {\n  message Nested {\n    int64 page = 1;\n    bool preview = 2;\n  }\n  Nested nested = 1;\n}\n\nmessage NestedListResponse {\n  message Nested {\n    int64 page = 1;\n  }\n  Nested nested = 1;\n  repeated string items = 2;\n}\n"
  },
  {
    "path": "packages/test-utils/proto/proto2.proto",
    "content": "// Copyright 2021-2023 The Connect Authors\n//\n// Licensed under the Apache License, Version 2.0 (the \"License\");\n// you may not use this file except in compliance with the License.\n// You may obtain a copy of the License at\n//\n//      http://www.apache.org/licenses/LICENSE-2.0\n//\n// Unless required by applicable law or agreed to in writing, software\n// distributed under the License is distributed on an \"AS IS\" BASIS,\n// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n// See the License for the specific language governing permissions and\n// limitations under the License.\n\nsyntax = \"proto2\";\npackage test;\n\nmessage Proto2Message {\n  optional string string_field = 1;\n  optional int32 int32_field = 3;\n}\n"
  },
  {
    "path": "packages/test-utils/proto/proto3.proto",
    "content": "// Copyright 2021-2023 The Connect Authors\n//\n// Licensed under the Apache License, Version 2.0 (the \"License\");\n// you may not use this file except in compliance with the License.\n// You may obtain a copy of the License at\n//\n//      http://www.apache.org/licenses/LICENSE-2.0\n//\n// Unless required by applicable law or agreed to in writing, software\n// distributed under the License is distributed on an \"AS IS\" BASIS,\n// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n// See the License for the specific language governing permissions and\n// limitations under the License.\n\nsyntax = \"proto3\";\npackage test;\n\n// Note: We do not exhaust all field types\nmessage Proto3Message {\n  string string_field = 1;\n  bytes bytes_field = 2;\n  int32 int32_field = 3;\n  int64 int64_field = 4;\n  double double_field = 5;\n  bool bool_field = 6;\n  Proto3Enum enum_field = 7;\n  Proto3Message message_field = 8;\n\n  optional string optional_string_field = 9;\n\n  repeated string repeated_string_field = 17;\n  repeated Proto3Message repeated_message_field = 18;\n  repeated Proto3Enum repeated_enum_field = 19;\n\n  oneof either {\n    string oneof_string_field = 31;\n    int32 oneof_int32_field = 33;\n  }\n\n  map<string, int64> map_string_int64_field = 39;\n  map<string, Proto3Message> map_string_message_field = 40;\n  map<string, Proto3Enum> map_string_enum_field = 41;\n}\n\nenum Proto3Enum {\n  PROTO3_ENUM_UNSPECIFIED = 0;\n  PROTO3_ENUM_YES = 1;\n  PROTO3_ENUM_NO = 2;\n}\n"
  },
  {
    "path": "packages/test-utils/src/gen/bigint_pb.ts",
    "content": "// Copyright 2021-2023 The Connect Authors\n//\n// Licensed under the Apache License, Version 2.0 (the \"License\");\n// you may not use this file except in compliance with the License.\n// You may obtain a copy of the License at\n//\n//      http://www.apache.org/licenses/LICENSE-2.0\n//\n// Unless required by applicable law or agreed to in writing, software\n// distributed under the License is distributed on an \"AS IS\" BASIS,\n// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n// See the License for the specific language governing permissions and\n// limitations under the License.\n\n// @generated by protoc-gen-es v2.6.2 with parameter \"target=ts\"\n// @generated from file bigint.proto (syntax proto3)\n/* eslint-disable */\n\nimport type { GenFile, GenMessage, GenService } from \"@bufbuild/protobuf/codegenv2\";\nimport { fileDesc, messageDesc, serviceDesc } from \"@bufbuild/protobuf/codegenv2\";\nimport type { EmptySchema } from \"@bufbuild/protobuf/wkt\";\nimport { file_google_protobuf_empty } from \"@bufbuild/protobuf/wkt\";\nimport type { Message } from \"@bufbuild/protobuf\";\n\n/**\n * Describes the file bigint.proto.\n */\nexport const file_bigint: GenFile = /*@__PURE__*/\n  fileDesc(\"CgxiaWdpbnQucHJvdG8iGwoMQ291bnRSZXF1ZXN0EgsKA2FkZBgBIAEoAyIeCg1Db3VudFJlc3BvbnNlEg0KBWNvdW50GAEgASgDMmsKDUJpZ0ludFNlcnZpY2USJgoFQ291bnQSDS5Db3VudFJlcXVlc3QaDi5Db3VudFJlc3BvbnNlEjIKCEdldENvdW50EhYuZ29vZ2xlLnByb3RvYnVmLkVtcHR5Gg4uQ291bnRSZXNwb25zZWIGcHJvdG8z\", [file_google_protobuf_empty]);\n\n/**\n * @generated from message CountRequest\n */\nexport type CountRequest = Message<\"CountRequest\"> & {\n  /**\n   * @generated from field: int64 add = 1;\n   */\n  add: bigint;\n};\n\n/**\n * Describes the message CountRequest.\n * Use `create(CountRequestSchema)` to create a new message.\n */\nexport const CountRequestSchema: GenMessage<CountRequest> = /*@__PURE__*/\n  messageDesc(file_bigint, 0);\n\n/**\n * @generated from message CountResponse\n */\nexport type CountResponse = Message<\"CountResponse\"> & {\n  /**\n   * @generated from field: int64 count = 1;\n   */\n  count: bigint;\n};\n\n/**\n * Describes the message CountResponse.\n * Use `create(CountResponseSchema)` to create a new message.\n */\nexport const CountResponseSchema: GenMessage<CountResponse> = /*@__PURE__*/\n  messageDesc(file_bigint, 1);\n\n/**\n * @generated from service BigIntService\n */\nexport const BigIntService: GenService<{\n  /**\n   * @generated from rpc BigIntService.Count\n   */\n  count: {\n    methodKind: \"unary\";\n    input: typeof CountRequestSchema;\n    output: typeof CountResponseSchema;\n  },\n  /**\n   * @generated from rpc BigIntService.GetCount\n   */\n  getCount: {\n    methodKind: \"unary\";\n    input: typeof EmptySchema;\n    output: typeof CountResponseSchema;\n  },\n}> = /*@__PURE__*/\n  serviceDesc(file_bigint, 0);\n\n"
  },
  {
    "path": "packages/test-utils/src/gen/eliza_pb.ts",
    "content": "// Copyright 2021-2023 The Connect Authors\n//\n// Licensed under the Apache License, Version 2.0 (the \"License\");\n// you may not use this file except in compliance with the License.\n// You may obtain a copy of the License at\n//\n//      http://www.apache.org/licenses/LICENSE-2.0\n//\n// Unless required by applicable law or agreed to in writing, software\n// distributed under the License is distributed on an \"AS IS\" BASIS,\n// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n// See the License for the specific language governing permissions and\n// limitations under the License.\n\n// @generated by protoc-gen-es v2.6.2 with parameter \"target=ts\"\n// @generated from file eliza.proto (package connectrpc.eliza.v1, syntax proto3)\n/* eslint-disable */\n\nimport type { GenFile, GenMessage, GenService } from \"@bufbuild/protobuf/codegenv2\";\nimport { fileDesc, messageDesc, serviceDesc } from \"@bufbuild/protobuf/codegenv2\";\nimport type { Message } from \"@bufbuild/protobuf\";\n\n/**\n * Describes the file eliza.proto.\n */\nexport const file_eliza: GenFile = /*@__PURE__*/\n  fileDesc(\"CgtlbGl6YS5wcm90bxITY29ubmVjdHJwYy5lbGl6YS52MSIeCgpTYXlSZXF1ZXN0EhAKCHNlbnRlbmNlGAEgASgJIh8KC1NheVJlc3BvbnNlEhAKCHNlbnRlbmNlGAEgASgJMloKDEVsaXphU2VydmljZRJKCgNTYXkSHy5jb25uZWN0cnBjLmVsaXphLnYxLlNheVJlcXVlc3QaIC5jb25uZWN0cnBjLmVsaXphLnYxLlNheVJlc3BvbnNlIgBiBnByb3RvMw\");\n\n/**\n * SayRequest is a single-sentence request.\n *\n * @generated from message connectrpc.eliza.v1.SayRequest\n */\nexport type SayRequest = Message<\"connectrpc.eliza.v1.SayRequest\"> & {\n  /**\n   * @generated from field: string sentence = 1;\n   */\n  sentence: string;\n};\n\n/**\n * Describes the message connectrpc.eliza.v1.SayRequest.\n * Use `create(SayRequestSchema)` to create a new message.\n */\nexport const SayRequestSchema: GenMessage<SayRequest> = /*@__PURE__*/\n  messageDesc(file_eliza, 0);\n\n/**\n * SayResponse is a single-sentence response.\n *\n * @generated from message connectrpc.eliza.v1.SayResponse\n */\nexport type SayResponse = Message<\"connectrpc.eliza.v1.SayResponse\"> & {\n  /**\n   * @generated from field: string sentence = 1;\n   */\n  sentence: string;\n};\n\n/**\n * Describes the message connectrpc.eliza.v1.SayResponse.\n * Use `create(SayResponseSchema)` to create a new message.\n */\nexport const SayResponseSchema: GenMessage<SayResponse> = /*@__PURE__*/\n  messageDesc(file_eliza, 1);\n\n/**\n * ElizaService provides a way to talk to Eliza, a port of the DOCTOR script\n * for Joseph Weizenbaum's original ELIZA program. Created in the mid-1960s at\n * the MIT Artificial Intelligence Laboratory, ELIZA demonstrates the\n * superficiality of human-computer communication. DOCTOR simulates a\n * psychotherapist, and is commonly found as an Easter egg in emacs\n * distributions.\n *\n * @generated from service connectrpc.eliza.v1.ElizaService\n */\nexport const ElizaService: GenService<{\n  /**\n   * Say is a unary RPC. Eliza responds to the prompt with a single sentence.\n   *\n   * @generated from rpc connectrpc.eliza.v1.ElizaService.Say\n   */\n  say: {\n    methodKind: \"unary\";\n    input: typeof SayRequestSchema;\n    output: typeof SayResponseSchema;\n  },\n}> = /*@__PURE__*/\n  serviceDesc(file_eliza, 0);\n\n"
  },
  {
    "path": "packages/test-utils/src/gen/list_pb.ts",
    "content": "// Copyright 2021-2023 The Connect Authors\n//\n// Licensed under the Apache License, Version 2.0 (the \"License\");\n// you may not use this file except in compliance with the License.\n// You may obtain a copy of the License at\n//\n//      http://www.apache.org/licenses/LICENSE-2.0\n//\n// Unless required by applicable law or agreed to in writing, software\n// distributed under the License is distributed on an \"AS IS\" BASIS,\n// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n// See the License for the specific language governing permissions and\n// limitations under the License.\n\n// @generated by protoc-gen-es v2.6.2 with parameter \"target=ts\"\n// @generated from file list.proto (syntax proto3)\n/* eslint-disable */\n\nimport type { GenFile, GenMessage, GenService } from \"@bufbuild/protobuf/codegenv2\";\nimport { fileDesc, messageDesc, serviceDesc } from \"@bufbuild/protobuf/codegenv2\";\nimport type { Message } from \"@bufbuild/protobuf\";\n\n/**\n * Describes the file list.proto.\n */\nexport const file_list: GenFile = /*@__PURE__*/\n  fileDesc(\"CgpsaXN0LnByb3RvIiwKC0xpc3RSZXF1ZXN0EgwKBHBhZ2UYASABKAMSDwoHcHJldmlldxgCIAEoCCIrCgxMaXN0UmVzcG9uc2USDAoEcGFnZRgBIAEoAxINCgVpdGVtcxgCIAMoCSJnChFOZXN0ZWRMaXN0UmVxdWVzdBIpCgZuZXN0ZWQYASABKAsyGS5OZXN0ZWRMaXN0UmVxdWVzdC5OZXN0ZWQaJwoGTmVzdGVkEgwKBHBhZ2UYASABKAMSDwoHcHJldmlldxgCIAEoCCJnChJOZXN0ZWRMaXN0UmVzcG9uc2USKgoGbmVzdGVkGAEgASgLMhouTmVzdGVkTGlzdFJlc3BvbnNlLk5lc3RlZBINCgVpdGVtcxgCIAMoCRoWCgZOZXN0ZWQSDAoEcGFnZRgBIAEoAzJpCgtMaXN0U2VydmljZRIjCgRMaXN0EgwuTGlzdFJlcXVlc3QaDS5MaXN0UmVzcG9uc2USNQoKTmVzdGVkTGlzdBISLk5lc3RlZExpc3RSZXF1ZXN0GhMuTmVzdGVkTGlzdFJlc3BvbnNlYgZwcm90bzM\");\n\n/**\n * @generated from message ListRequest\n */\nexport type ListRequest = Message<\"ListRequest\"> & {\n  /**\n   * @generated from field: int64 page = 1;\n   */\n  page: bigint;\n\n  /**\n   * @generated from field: bool preview = 2;\n   */\n  preview: boolean;\n};\n\n/**\n * Describes the message ListRequest.\n * Use `create(ListRequestSchema)` to create a new message.\n */\nexport const ListRequestSchema: GenMessage<ListRequest> = /*@__PURE__*/\n  messageDesc(file_list, 0);\n\n/**\n * @generated from message ListResponse\n */\nexport type ListResponse = Message<\"ListResponse\"> & {\n  /**\n   * @generated from field: int64 page = 1;\n   */\n  page: bigint;\n\n  /**\n   * @generated from field: repeated string items = 2;\n   */\n  items: string[];\n};\n\n/**\n * Describes the message ListResponse.\n * Use `create(ListResponseSchema)` to create a new message.\n */\nexport const ListResponseSchema: GenMessage<ListResponse> = /*@__PURE__*/\n  messageDesc(file_list, 1);\n\n/**\n * @generated from message NestedListRequest\n */\nexport type NestedListRequest = Message<\"NestedListRequest\"> & {\n  /**\n   * @generated from field: NestedListRequest.Nested nested = 1;\n   */\n  nested?: NestedListRequest_Nested;\n};\n\n/**\n * Describes the message NestedListRequest.\n * Use `create(NestedListRequestSchema)` to create a new message.\n */\nexport const NestedListRequestSchema: GenMessage<NestedListRequest> = /*@__PURE__*/\n  messageDesc(file_list, 2);\n\n/**\n * @generated from message NestedListRequest.Nested\n */\nexport type NestedListRequest_Nested = Message<\"NestedListRequest.Nested\"> & {\n  /**\n   * @generated from field: int64 page = 1;\n   */\n  page: bigint;\n\n  /**\n   * @generated from field: bool preview = 2;\n   */\n  preview: boolean;\n};\n\n/**\n * Describes the message NestedListRequest.Nested.\n * Use `create(NestedListRequest_NestedSchema)` to create a new message.\n */\nexport const NestedListRequest_NestedSchema: GenMessage<NestedListRequest_Nested> = /*@__PURE__*/\n  messageDesc(file_list, 2, 0);\n\n/**\n * @generated from message NestedListResponse\n */\nexport type NestedListResponse = Message<\"NestedListResponse\"> & {\n  /**\n   * @generated from field: NestedListResponse.Nested nested = 1;\n   */\n  nested?: NestedListResponse_Nested;\n\n  /**\n   * @generated from field: repeated string items = 2;\n   */\n  items: string[];\n};\n\n/**\n * Describes the message NestedListResponse.\n * Use `create(NestedListResponseSchema)` to create a new message.\n */\nexport const NestedListResponseSchema: GenMessage<NestedListResponse> = /*@__PURE__*/\n  messageDesc(file_list, 3);\n\n/**\n * @generated from message NestedListResponse.Nested\n */\nexport type NestedListResponse_Nested = Message<\"NestedListResponse.Nested\"> & {\n  /**\n   * @generated from field: int64 page = 1;\n   */\n  page: bigint;\n};\n\n/**\n * Describes the message NestedListResponse.Nested.\n * Use `create(NestedListResponse_NestedSchema)` to create a new message.\n */\nexport const NestedListResponse_NestedSchema: GenMessage<NestedListResponse_Nested> = /*@__PURE__*/\n  messageDesc(file_list, 3, 0);\n\n/**\n * @generated from service ListService\n */\nexport const ListService: GenService<{\n  /**\n   * @generated from rpc ListService.List\n   */\n  list: {\n    methodKind: \"unary\";\n    input: typeof ListRequestSchema;\n    output: typeof ListResponseSchema;\n  },\n  /**\n   * @generated from rpc ListService.NestedList\n   */\n  nestedList: {\n    methodKind: \"unary\";\n    input: typeof NestedListRequestSchema;\n    output: typeof NestedListResponseSchema;\n  },\n}> = /*@__PURE__*/\n  serviceDesc(file_list, 0);\n\n"
  },
  {
    "path": "packages/test-utils/src/gen/proto2_pb.ts",
    "content": "// Copyright 2021-2023 The Connect Authors\n//\n// Licensed under the Apache License, Version 2.0 (the \"License\");\n// you may not use this file except in compliance with the License.\n// You may obtain a copy of the License at\n//\n//      http://www.apache.org/licenses/LICENSE-2.0\n//\n// Unless required by applicable law or agreed to in writing, software\n// distributed under the License is distributed on an \"AS IS\" BASIS,\n// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n// See the License for the specific language governing permissions and\n// limitations under the License.\n\n// @generated by protoc-gen-es v2.6.2 with parameter \"target=ts\"\n// @generated from file proto2.proto (package test, syntax proto2)\n/* eslint-disable */\n\nimport type { GenFile, GenMessage } from \"@bufbuild/protobuf/codegenv2\";\nimport { fileDesc, messageDesc } from \"@bufbuild/protobuf/codegenv2\";\nimport type { Message } from \"@bufbuild/protobuf\";\n\n/**\n * Describes the file proto2.proto.\n */\nexport const file_proto2: GenFile = /*@__PURE__*/\n  fileDesc(\"Cgxwcm90bzIucHJvdG8SBHRlc3QiOgoNUHJvdG8yTWVzc2FnZRIUCgxzdHJpbmdfZmllbGQYASABKAkSEwoLaW50MzJfZmllbGQYAyABKAU\");\n\n/**\n * @generated from message test.Proto2Message\n */\nexport type Proto2Message = Message<\"test.Proto2Message\"> & {\n  /**\n   * @generated from field: optional string string_field = 1;\n   */\n  stringField: string;\n\n  /**\n   * @generated from field: optional int32 int32_field = 3;\n   */\n  int32Field: number;\n};\n\n/**\n * Describes the message test.Proto2Message.\n * Use `create(Proto2MessageSchema)` to create a new message.\n */\nexport const Proto2MessageSchema: GenMessage<Proto2Message> = /*@__PURE__*/\n  messageDesc(file_proto2, 0);\n\n"
  },
  {
    "path": "packages/test-utils/src/gen/proto3_pb.ts",
    "content": "// Copyright 2021-2023 The Connect Authors\n//\n// Licensed under the Apache License, Version 2.0 (the \"License\");\n// you may not use this file except in compliance with the License.\n// You may obtain a copy of the License at\n//\n//      http://www.apache.org/licenses/LICENSE-2.0\n//\n// Unless required by applicable law or agreed to in writing, software\n// distributed under the License is distributed on an \"AS IS\" BASIS,\n// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n// See the License for the specific language governing permissions and\n// limitations under the License.\n\n// @generated by protoc-gen-es v2.6.2 with parameter \"target=ts\"\n// @generated from file proto3.proto (package test, syntax proto3)\n/* eslint-disable */\n\nimport type { GenEnum, GenFile, GenMessage } from \"@bufbuild/protobuf/codegenv2\";\nimport { enumDesc, fileDesc, messageDesc } from \"@bufbuild/protobuf/codegenv2\";\nimport type { Message } from \"@bufbuild/protobuf\";\n\n/**\n * Describes the file proto3.proto.\n */\nexport const file_proto3: GenFile = /*@__PURE__*/\n  fileDesc(\"Cgxwcm90bzMucHJvdG8SBHRlc3QirgcKDVByb3RvM01lc3NhZ2USFAoMc3RyaW5nX2ZpZWxkGAEgASgJEhMKC2J5dGVzX2ZpZWxkGAIgASgMEhMKC2ludDMyX2ZpZWxkGAMgASgFEhMKC2ludDY0X2ZpZWxkGAQgASgDEhQKDGRvdWJsZV9maWVsZBgFIAEoARISCgpib29sX2ZpZWxkGAYgASgIEiQKCmVudW1fZmllbGQYByABKA4yEC50ZXN0LlByb3RvM0VudW0SKgoNbWVzc2FnZV9maWVsZBgIIAEoCzITLnRlc3QuUHJvdG8zTWVzc2FnZRIiChVvcHRpb25hbF9zdHJpbmdfZmllbGQYCSABKAlIAYgBARIdChVyZXBlYXRlZF9zdHJpbmdfZmllbGQYESADKAkSMwoWcmVwZWF0ZWRfbWVzc2FnZV9maWVsZBgSIAMoCzITLnRlc3QuUHJvdG8zTWVzc2FnZRItChNyZXBlYXRlZF9lbnVtX2ZpZWxkGBMgAygOMhAudGVzdC5Qcm90bzNFbnVtEhwKEm9uZW9mX3N0cmluZ19maWVsZBgfIAEoCUgAEhsKEW9uZW9mX2ludDMyX2ZpZWxkGCEgASgFSAASTAoWbWFwX3N0cmluZ19pbnQ2NF9maWVsZBgnIAMoCzIsLnRlc3QuUHJvdG8zTWVzc2FnZS5NYXBTdHJpbmdJbnQ2NEZpZWxkRW50cnkSUAoYbWFwX3N0cmluZ19tZXNzYWdlX2ZpZWxkGCggAygLMi4udGVzdC5Qcm90bzNNZXNzYWdlLk1hcFN0cmluZ01lc3NhZ2VGaWVsZEVudHJ5EkoKFW1hcF9zdHJpbmdfZW51bV9maWVsZBgpIAMoCzIrLnRlc3QuUHJvdG8zTWVzc2FnZS5NYXBTdHJpbmdFbnVtRmllbGRFbnRyeRo6ChhNYXBTdHJpbmdJbnQ2NEZpZWxkRW50cnkSCwoDa2V5GAEgASgJEg0KBXZhbHVlGAIgASgDOgI4ARpRChpNYXBTdHJpbmdNZXNzYWdlRmllbGRFbnRyeRILCgNrZXkYASABKAkSIgoFdmFsdWUYAiABKAsyEy50ZXN0LlByb3RvM01lc3NhZ2U6AjgBGksKF01hcFN0cmluZ0VudW1GaWVsZEVudHJ5EgsKA2tleRgBIAEoCRIfCgV2YWx1ZRgCIAEoDjIQLnRlc3QuUHJvdG8zRW51bToCOAFCCAoGZWl0aGVyQhgKFl9vcHRpb25hbF9zdHJpbmdfZmllbGQqUgoKUHJvdG8zRW51bRIbChdQUk9UTzNfRU5VTV9VTlNQRUNJRklFRBAAEhMKD1BST1RPM19FTlVNX1lFUxABEhIKDlBST1RPM19FTlVNX05PEAJiBnByb3RvMw\");\n\n/**\n * Note: We do not exhaust all field types\n *\n * @generated from message test.Proto3Message\n */\nexport type Proto3Message = Message<\"test.Proto3Message\"> & {\n  /**\n   * @generated from field: string string_field = 1;\n   */\n  stringField: string;\n\n  /**\n   * @generated from field: bytes bytes_field = 2;\n   */\n  bytesField: Uint8Array;\n\n  /**\n   * @generated from field: int32 int32_field = 3;\n   */\n  int32Field: number;\n\n  /**\n   * @generated from field: int64 int64_field = 4;\n   */\n  int64Field: bigint;\n\n  /**\n   * @generated from field: double double_field = 5;\n   */\n  doubleField: number;\n\n  /**\n   * @generated from field: bool bool_field = 6;\n   */\n  boolField: boolean;\n\n  /**\n   * @generated from field: test.Proto3Enum enum_field = 7;\n   */\n  enumField: Proto3Enum;\n\n  /**\n   * @generated from field: test.Proto3Message message_field = 8;\n   */\n  messageField?: Proto3Message;\n\n  /**\n   * @generated from field: optional string optional_string_field = 9;\n   */\n  optionalStringField?: string;\n\n  /**\n   * @generated from field: repeated string repeated_string_field = 17;\n   */\n  repeatedStringField: string[];\n\n  /**\n   * @generated from field: repeated test.Proto3Message repeated_message_field = 18;\n   */\n  repeatedMessageField: Proto3Message[];\n\n  /**\n   * @generated from field: repeated test.Proto3Enum repeated_enum_field = 19;\n   */\n  repeatedEnumField: Proto3Enum[];\n\n  /**\n   * @generated from oneof test.Proto3Message.either\n   */\n  either: {\n    /**\n     * @generated from field: string oneof_string_field = 31;\n     */\n    value: string;\n    case: \"oneofStringField\";\n  } | {\n    /**\n     * @generated from field: int32 oneof_int32_field = 33;\n     */\n    value: number;\n    case: \"oneofInt32Field\";\n  } | { case: undefined; value?: undefined };\n\n  /**\n   * @generated from field: map<string, int64> map_string_int64_field = 39;\n   */\n  mapStringInt64Field: { [key: string]: bigint };\n\n  /**\n   * @generated from field: map<string, test.Proto3Message> map_string_message_field = 40;\n   */\n  mapStringMessageField: { [key: string]: Proto3Message };\n\n  /**\n   * @generated from field: map<string, test.Proto3Enum> map_string_enum_field = 41;\n   */\n  mapStringEnumField: { [key: string]: Proto3Enum };\n};\n\n/**\n * Describes the message test.Proto3Message.\n * Use `create(Proto3MessageSchema)` to create a new message.\n */\nexport const Proto3MessageSchema: GenMessage<Proto3Message> = /*@__PURE__*/\n  messageDesc(file_proto3, 0);\n\n/**\n * @generated from enum test.Proto3Enum\n */\nexport enum Proto3Enum {\n  /**\n   * @generated from enum value: PROTO3_ENUM_UNSPECIFIED = 0;\n   */\n  UNSPECIFIED = 0,\n\n  /**\n   * @generated from enum value: PROTO3_ENUM_YES = 1;\n   */\n  YES = 1,\n\n  /**\n   * @generated from enum value: PROTO3_ENUM_NO = 2;\n   */\n  NO = 2,\n}\n\n/**\n * Describes the enum test.Proto3Enum.\n */\nexport const Proto3EnumSchema: GenEnum<Proto3Enum> = /*@__PURE__*/\n  enumDesc(file_proto3, 0);\n\n"
  },
  {
    "path": "packages/test-utils/src/index.tsx",
    "content": "// Copyright 2021-2023 The Connect Authors\n//\n// Licensed under the Apache License, Version 2.0 (the \"License\");\n// you may not use this file except in compliance with the License.\n// You may obtain a copy of the License at\n//\n//      http://www.apache.org/licenses/LICENSE-2.0\n//\n// Unless required by applicable law or agreed to in writing, software\n// distributed under the License is distributed on an \"AS IS\" BASIS,\n// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n// See the License for the specific language governing permissions and\n// limitations under the License.\n\nimport type { MessageInitShape } from \"@bufbuild/protobuf\";\nimport { create } from \"@bufbuild/protobuf\";\nimport {\n  createRouterTransport,\n  type ConnectRouterOptions,\n} from \"@connectrpc/connect\";\n\nimport {\n  BigIntService,\n  type CountRequest,\n  CountResponseSchema,\n} from \"./gen/bigint_pb.js\";\nimport {\n  ElizaService,\n  type SayRequest,\n  SayResponseSchema,\n} from \"./gen/eliza_pb.js\";\nimport {\n  type ListResponseSchema,\n  ListService,\n  type NestedListResponseSchema,\n} from \"./gen/list_pb.js\";\n\n/**\n * A test-only helper to increase time (necessary for testing react-query)\n */\nexport const sleep = async (timeout: number) =>\n  new Promise((resolve) => {\n    setTimeout(resolve, timeout);\n  });\n\n/**\n * a stateless mock for ElizaService\n */\nexport const mockEliza = (\n  override?: MessageInitShape<typeof SayResponseSchema>,\n  addDelay = false,\n  options?: {\n    router?: ConnectRouterOptions;\n  },\n) =>\n  createRouterTransport(\n    ({ service }) => {\n      service(ElizaService, {\n        say: async (input: SayRequest) => {\n          if (addDelay) {\n            await sleep(1000);\n          }\n          return create(\n            SayResponseSchema,\n            override ?? { sentence: `Hello ${input.sentence}` },\n          );\n        },\n      });\n    },\n    {\n      router: options?.router,\n    },\n  );\n\n/**\n * a stateless mock for BigIntService\n */\nexport const mockBigInt = () =>\n  createRouterTransport(({ service }) => {\n    service(BigIntService, {\n      count: () => create(CountResponseSchema, { count: 1n }),\n    });\n  });\n\n/**\n * a mock for BigIntService that acts as an impromptu database\n */\nexport const mockStatefulBigIntTransport = (addDelay = false) =>\n  createRouterTransport(({ service }) => {\n    let count = 0n;\n    service(BigIntService, {\n      count: async (request?: CountRequest) => {\n        if (addDelay) {\n          await sleep(1000);\n        }\n        if (request) {\n          count += request.add;\n        }\n        return create(CountResponseSchema, { count });\n      },\n      getCount: () => create(CountResponseSchema, { count }),\n    });\n  });\n\n/**\n * a mock for PaginatedService that acts as an impromptu database\n */\nexport const mockPaginatedTransport = (\n  override?: MessageInitShape<typeof ListResponseSchema>,\n  addDelay = false,\n  options?: {\n    router?: ConnectRouterOptions;\n  },\n) =>\n  createRouterTransport(\n    ({ service }) => {\n      service(ListService, {\n        list: async (request) => {\n          if (addDelay) {\n            await sleep(1000);\n          }\n          if (override !== undefined) {\n            return override;\n          }\n          const base = (request.page - 1n) * 3n;\n          const result = {\n            page: request.page,\n            items: [\n              `${base + 1n} Item`,\n              `${base + 2n} Item`,\n              `${base + 3n} Item`,\n            ],\n          };\n          return result;\n        },\n      });\n    },\n    {\n      router: options?.router,\n    },\n  );\n\n/**\n * a mock for nested paginated list queries\n */\nexport const mockNestedPaginatedTransport = (\n  override?: MessageInitShape<typeof NestedListResponseSchema>,\n  addDelay = false,\n  options?: {\n    router?: ConnectRouterOptions;\n  },\n) =>\n  createRouterTransport(\n    ({ service }) => {\n      service(ListService, {\n        nestedList: async (request) => {\n          if (addDelay) {\n            await sleep(1000);\n          }\n          if (override !== undefined) {\n            return override;\n          }\n          const page = request.nested?.page ?? 0n;\n          const base = (page - 1n) * 3n;\n          return {\n            nested: {\n              page,\n            },\n            items: [\n              `${base + 1n} Item`,\n              `${base + 2n} Item`,\n              `${base + 3n} Item`,\n            ],\n          };\n        },\n      });\n    },\n    {\n      router: options?.router,\n    },\n  );\n"
  },
  {
    "path": "packages/test-utils/tsconfig.json",
    "content": "{\n  \"include\": [\"src/\"],\n  \"extends\": \"../../tsconfig.base.json\"\n}\n"
  },
  {
    "path": "scripts/find-workspace-version.js",
    "content": "// Copyright 2021-2023 The Connect Authors\n//\n// Licensed under the Apache License, Version 2.0 (the \"License\");\n// you may not use this file except in compliance with the License.\n// You may obtain a copy of the License at\n//\n//      http://www.apache.org/licenses/LICENSE-2.0\n//\n// Unless required by applicable law or agreed to in writing, software\n// distributed under the License is distributed on an \"AS IS\" BASIS,\n// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n// See the License for the specific language governing permissions and\n// limitations under the License.\n\nimport { findWorkspaceVersion } from \"./utils.js\";\n\nprocess.stdout.write(`${findWorkspaceVersion(\"packages\")}\\n`);\n"
  },
  {
    "path": "scripts/gh-diffcheck.js",
    "content": "// Copyright 2021-2023 The Connect Authors\n//\n// Licensed under the Apache License, Version 2.0 (the \"License\");\n// you may not use this file except in compliance with the License.\n// You may obtain a copy of the License at\n//\n//      http://www.apache.org/licenses/LICENSE-2.0\n//\n// Unless required by applicable law or agreed to in writing, software\n// distributed under the License is distributed on an \"AS IS\" BASIS,\n// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n// See the License for the specific language governing permissions and\n// limitations under the License.\n\nimport { execSync } from \"node:child_process\";\n\nif (gitUncommitted()) {\n  process.stdout.write(\n    \"::error::Uncommitted changes found. Please make sure this branch is up to date, and run the command locally (for example `npx turbo format`). \" +\n      \"Verify the changes are what you want and commit them.\\n\",\n  );\n  execSync(\"git --no-pager diff\", {\n    stdio: \"inherit\",\n  });\n  process.exit(1);\n}\n\n/**\n * @returns {boolean}\n */\nfunction gitUncommitted() {\n  const out = execSync(\"git status --porcelain\", {\n    encoding: \"utf-8\",\n  });\n  return out.trim().length > 0;\n}\n"
  },
  {
    "path": "scripts/release.js",
    "content": "// Copyright 2021-2023 The Connect Authors\n//\n// Licensed under the Apache License, Version 2.0 (the \"License\");\n// you may not use this file except in compliance with the License.\n// You may obtain a copy of the License at\n//\n//      http://www.apache.org/licenses/LICENSE-2.0\n//\n// Unless required by applicable law or agreed to in writing, software\n// distributed under the License is distributed on an \"AS IS\" BASIS,\n// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n// See the License for the specific language governing permissions and\n// limitations under the License.\n\nimport { execSync } from \"node:child_process\";\nimport { findWorkspaceVersion } from \"./utils.js\";\n\n/*\n * Publish connect-query\n *\n * Recommended procedure:\n * 1. Trigger the prepare-release workflow with the version you want to release.\n * 2. Reviews release notes in the created PR, wait for approval.\n * 3. Merge the PR.\n */\n\nconst tag = determinePublishTag(findWorkspaceVersion(\"packages\"));\nconst uncommitted = gitUncommitted();\nif (uncommitted.length > 0) {\n  throw new Error(\"Uncommitted changes found: \\n\" + uncommitted);\n}\nnpmPublish();\n\n/**\n *\n */\nfunction npmPublish() {\n  const command =\n    `npm publish --tag ${tag}` +\n    \" --workspace packages/connect-query\" +\n    \" --workspace packages/connect-query-core\" +\n    \" --workspace packages/protoc-gen-connect-query\";\n  execSync(command, {\n    stdio: \"inherit\",\n  });\n}\n\n/**\n * @returns {string}\n */\nfunction gitUncommitted() {\n  const out = execSync(\"git status --short\", {\n    encoding: \"utf-8\",\n  });\n  if (out.trim().length === 0) {\n    return \"\";\n  }\n  return out;\n}\n\n/**\n * @param {string} version\n * @returns {string}\n */\nfunction determinePublishTag(version) {\n  if (/^\\d+\\.\\d+\\.\\d+$/.test(version)) {\n    return \"latest\";\n  } else if (/^\\d+\\.\\d+\\.\\d+-alpha.*$/.test(version)) {\n    return \"alpha\";\n  } else if (/^\\d+\\.\\d+\\.\\d+-beta.*$/.test(version)) {\n    return \"beta\";\n  } else if (/^\\d+\\.\\d+\\.\\d+-rc.*$/.test(version)) {\n    return \"rc\";\n  } else {\n    throw new Error(`Unable to determine publish tag from version ${version}`);\n  }\n}\n"
  },
  {
    "path": "scripts/set-workspace-version.js",
    "content": "#!/usr/bin/env node\n\n// Copyright 2021-2023 The Connect Authors\n//\n// Licensed under the Apache License, Version 2.0 (the \"License\");\n// you may not use this file except in compliance with the License.\n// You may obtain a copy of the License at\n//\n//      http://www.apache.org/licenses/LICENSE-2.0\n//\n// Unless required by applicable law or agreed to in writing, software\n// distributed under the License is distributed on an \"AS IS\" BASIS,\n// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n// See the License for the specific language governing permissions and\n// limitations under the License.\n\n// eslint-disable-next-line n/no-unsupported-features/node-builtins\nimport { readFileSync, writeFileSync, existsSync, globSync } from \"node:fs\";\nimport { dirname, join } from \"node:path\";\n\n// Ensures that a valid semver version is provided\n// See https://semver.org/#is-there-a-suggested-regular-expression-regex-to-check-a-semver-string\nconst versionRegex =\n  /^(0|[1-9]\\d*)\\.(0|[1-9]\\d*)\\.(0|[1-9]\\d*)(?:-((?:0|[1-9]\\d*|\\d*[a-zA-Z-][0-9a-zA-Z-]*)(?:\\.(?:0|[1-9]\\d*|\\d*[a-zA-Z-][0-9a-zA-Z-]*))*))?(?:\\+([0-9a-zA-Z-]+(?:\\.[0-9a-zA-Z-]+)*))?$/;\nif (process.argv.length !== 3 || !versionRegex.test(process.argv[2])) {\n  process.stderr.write(\n    [\n      `USAGE: ${process.argv[1]} <new-version>`,\n      \"\",\n      \"Walks through all workspace packages and sets the version of each \",\n      \"package to the given version.\",\n      \"If a package depends on another package from the workspace, the\",\n      \"dependency version is updated as well.\",\n      \"\",\n      ...(versionRegex.test(process.argv[2])\n        ? []\n        : [\n            \"Version provided is not a valid semver version.\",\n            \"Please provide a version in the format MAJOR.MINOR.PATCH[-PRERELEASE+BUILD].\",\n          ]),\n    ].join(\"\\n\"),\n  );\n  process.exit(1);\n}\nconst newVersion = process.argv[2];\nconst rootPackagePath = \"package.json\";\nconst lockFilePath = \"package-lock.json\";\n\ntry {\n  const lock = readLockfile(lockFilePath);\n  const workspaces = readWorkspaces(rootPackagePath);\n  const allPackages = workspaces.map((ws) => ws.pkg);\n  const bumpPackages = allPackages.filter(\n    (pkg) => pkg.version !== undefined && pkg.version !== newVersion,\n  );\n  /** @type {Log[]} */\n  const log = [];\n  for (const pkg of bumpPackages) {\n    log.push({\n      pkg,\n      message: `updated version from ${pkg.version} to ${newVersion}`,\n    });\n    pkg.version = newVersion;\n    findLockPackage(lock, pkg.name).version = newVersion;\n  }\n  for (const pkg of bumpPackages) {\n    // update deps in workspace package.json\n    for (const other of allPackages) {\n      log.push(...updatePackageDep(other, pkg.name, newVersion));\n    }\n    // update deps in package-lock.json\n    for (const lockPkg of Object.values(lock.packages)) {\n      updatePackageDep(lockPkg, pkg.name, newVersion);\n    }\n  }\n  if (log.length > 0) {\n    for (const { path, pkg } of workspaces) {\n      writeJson(path, pkg);\n    }\n    writeJson(lockFilePath, lock);\n    process.stdout.write(formatLog(log) + \"\\n\");\n  }\n} catch (e) {\n  process.stderr.write(String(e) + \"\\n\");\n  process.exit(1);\n}\n\n/**\n * @typedef {{path: string; pkg: Package}} Workspace\n */\n\n/**\n * Read the given root package.json file, and return an array of workspace\n * packages.\n *\n * @param {string} rootPackagePath\n * @return {Workspace[]}\n */\nfunction readWorkspaces(rootPackagePath) {\n  const root = readRootPackage(rootPackagePath);\n  const rootDir = dirname(rootPackagePath);\n  return root.workspaces\n    .flatMap((ws) => globSync(join(rootDir, ws, \"package.json\")))\n    .filter((path) => existsSync(path))\n    .map((path) => {\n      return { path, pkg: readPackage(path) };\n    });\n}\n\n/**\n * @typedef {{message: string, pkg: Package}} Log\n */\n\n/**\n * @param {Package|LockPackage} pkg\n * @param {string} depName\n * @param {string} toVersion\n * @return {Log[]}\n */\nfunction updatePackageDep(pkg, depName, toVersion) {\n  if (toVersion === undefined) {\n    throw new Error(\"toVersion undefined\");\n  }\n  /** @type {Log[]} */\n  const log = [];\n  for (const key of [\n    \"dependencies\",\n    \"devDependencies\",\n    \"peerDependencies\",\n    \"optionalDependencies\",\n  ]) {\n    // eslint-disable-next-line n/no-unsupported-features/es-builtins,n/no-unsupported-features/es-syntax\n    if (!Object.hasOwn(pkg, key)) {\n      continue;\n    }\n    /** @type { Record<string, string> } */\n    const deps = pkg[key];\n    const from = deps[depName];\n    if (from === undefined) {\n      continue;\n    }\n    let to;\n    if (from.startsWith(\"^\")) {\n      to = `^${toVersion}`;\n    } else if (from.startsWith(\"~\")) {\n      to = `~${toVersion}`;\n    } else if (from.startsWith(\"=\")) {\n      to = `=${toVersion}`;\n    } else if (from === \"*\") {\n      to = `*`;\n    } else {\n      to = toVersion;\n    }\n    if (from === to) {\n      continue;\n    }\n    deps[depName] = to;\n    log.push({\n      pkg,\n      message: `updated ${key}[\"${depName}\"] from ${from} to ${to}`,\n    });\n  }\n  return log;\n}\n\n/**\n *\n * @param {Log[]} log\n * @return {string}\n */\nfunction formatLog(log) {\n  const lines = [];\n  const updatesByName = {};\n  for (const l of log) {\n    if (updatesByName[l.pkg.name] === undefined) {\n      updatesByName[l.pkg.name] = [];\n    }\n    updatesByName[l.pkg.name].push(l);\n  }\n  for (const name of Object.keys(updatesByName).sort()) {\n    lines.push(`${name}:`);\n    for (const update of updatesByName[name]) {\n      lines.push(`  ${update.message}`);\n    }\n  }\n  return lines.join(\"\\n\");\n}\n\n/**\n * @typedef {{name: string; version?: string; private?: boolean}} Package\n */\n\n/**\n * @param {string} path\n * @return {Package}\n */\nfunction readPackage(path) {\n  const json = JSON.parse(readFileSync(path, \"utf-8\"));\n  if (typeof json !== \"object\" || json === null) {\n    throw new Error(`Failed to parse ${path}`);\n  }\n  const lock = JSON.parse(readFileSync(path, \"utf-8\"));\n  if (typeof lock !== \"object\" || lock === null) {\n    throw new Error(`Failed to parse ${path}`);\n  }\n  if (!(\"name\" in json) || typeof json.name != \"string\") {\n    throw new Error(`Missing \"name\" in ${path}`);\n  }\n  if (\"version\" in json) {\n    if (typeof json.version != \"string\") {\n      throw new Error(`Invalid \"version\" in ${path}`);\n    }\n  } else if (!(\"private\" in json) || json.private !== true) {\n    throw new Error(`Need either \"version\" or \"private\":true in ${path}`);\n  }\n  return lock;\n}\n\n/**\n * @typedef {{packages: Record<string, LockPackage>}} Lockfile\n */\n\n/**\n * @typedef {{name?: string; version?: string}} LockPackage\n */\n\n/**\n * @param {string} path\n * @return {Lockfile}\n */\nfunction readLockfile(path) {\n  const lock = JSON.parse(readFileSync(path, \"utf-8\"));\n  if (typeof lock !== \"object\" || lock === null) {\n    throw new Error(`Failed to parse ${path}`);\n  }\n  if (!(\"lockfileVersion\" in lock) || lock.lockfileVersion !== 3) {\n    throw new Error(`Unsupported lock file version in ${path}`);\n  }\n  if (typeof lock.packages != \"object\" || lock.packages == null) {\n    throw new Error(`Missing \"packages\" in ${path}`);\n  }\n  return lock;\n}\n\n/**\n * Locates an entry for a local workspace package in a lock file.\n * Throws an error if not found.\n *\n * @param {Lockfile} lock\n * @param {string} packageName\n * @return {LockPackage}\n */\nfunction findLockPackage(lock, packageName) {\n  for (const [path, lockPkg] of Object.entries(lock.packages)) {\n    // eslint-disable-next-line n/no-unsupported-features/es-builtins,n/no-unsupported-features/es-syntax\n    if (Object.hasOwn(lockPkg, \"name\") && lockPkg.name === packageName) {\n      return lockPkg;\n    }\n    // In some situations, the entry for a local package doesn't have a \"name\" property.\n    // We check the path of the entry instead: If the last path element is the same as\n    // the package name without scope, it's the entry we are looking for.\n    if (path.startsWith(\"node_modules/\")) {\n      // Not a local workspace package\n      continue;\n    }\n    const lastPathEle = path.split(\"/\").pop();\n    const packageShortname = packageName.split(\"/\").pop();\n    if (lastPathEle === packageShortname) {\n      return lockPkg;\n    }\n  }\n  throw new Error(\n    `Cannot find package ${packageName} in lock file. Run npm install?`,\n  );\n}\n\n/**\n * @typedef {{ name?: string; version?: string; workspaces: string[] }} RootPackage\n */\n\n/**\n * @param {string} path\n * @return {RootPackage}\n */\nfunction readRootPackage(path) {\n  const json = JSON.parse(readFileSync(path, \"utf-8\"));\n  if (typeof json !== \"object\" || json === null) {\n    throw new Error(`Failed to parse ${path}`);\n  }\n  if (\n    !Array.isArray(json.workspaces) ||\n    json.workspaces.some((w) => typeof w !== \"string\")\n  ) {\n    throw new Error(`Missing or malformed \"workspaces\" array in ${path}`);\n  }\n  return json;\n}\n\n/**\n * @param {string} path\n * @param {any} json\n */\nfunction writeJson(path, json) {\n  writeFileSync(path, JSON.stringify(json, null, 2) + \"\\n\");\n}\n"
  },
  {
    "path": "scripts/utils.js",
    "content": "// Copyright 2021-2023 The Connect Authors\n//\n// Licensed under the Apache License, Version 2.0 (the \"License\");\n// you may not use this file except in compliance with the License.\n// You may obtain a copy of the License at\n//\n//      http://www.apache.org/licenses/LICENSE-2.0\n//\n// Unless required by applicable law or agreed to in writing, software\n// distributed under the License is distributed on an \"AS IS\" BASIS,\n// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n// See the License for the specific language governing permissions and\n// limitations under the License.\n\nimport { readdirSync, readFileSync, existsSync } from \"node:fs\";\nimport { join } from \"node:path\";\n\n/**\n * Retrieves the workspace version from the package directory.\n *\n * @param {string} packagesDir\n * @returns {string}\n */\nexport function findWorkspaceVersion(packagesDir) {\n  let version = undefined;\n  for (const entry of readdirSync(packagesDir, { withFileTypes: true })) {\n    if (!entry.isDirectory()) {\n      continue;\n    }\n    const path = join(packagesDir, entry.name, \"package.json\");\n    if (existsSync(path)) {\n      const pkg = JSON.parse(readFileSync(path, \"utf-8\"));\n      if (pkg.private === true) {\n        continue;\n      }\n      if (!pkg.version) {\n        throw new Error(`${path} is missing \"version\"`);\n      }\n      if (version === undefined) {\n        version = pkg.version;\n      } else if (version !== pkg.version) {\n        throw new Error(`${path} has unexpected version ${pkg.version}`);\n      }\n    }\n  }\n  if (version === undefined) {\n    throw new Error(`unable to find workspace version`);\n  }\n  return version;\n}\n"
  },
  {
    "path": "tsconfig.base.json",
    "content": "{\n  \"compilerOptions\": {\n    \"target\": \"ES2020\",\n    \"lib\": [\n      \"ES2017\",\n      // DOM for the fetch and streams API\n      \"DOM\"\n    ],\n    \"esModuleInterop\": false,\n    \"forceConsistentCasingInFileNames\": true,\n    \"strict\": true,\n    \"noImplicitAny\": true,\n    \"strictNullChecks\": true,\n    \"strictFunctionTypes\": true,\n    \"strictBindCallApply\": true,\n    \"strictPropertyInitialization\": true,\n    \"noImplicitThis\": true,\n    \"useUnknownInCatchVariables\": true,\n    \"noUnusedLocals\": true,\n    \"noImplicitReturns\": true,\n    \"noFallthroughCasesInSwitch\": true,\n    \"noImplicitOverride\": true,\n\n    // We need node's module resolution, so we do not have to skip lib checks\n    \"moduleResolution\": \"Node16\",\n    \"module\": \"Node16\",\n    \"verbatimModuleSyntax\": true,\n    \"skipLibCheck\": false\n  }\n}\n"
  },
  {
    "path": "turbo.json",
    "content": "{\n  \"$schema\": \"https://turbo.build/schema.json\",\n  \"tasks\": {\n    \"build\": {\n      \"dependsOn\": [\"^build\", \"generate\"],\n      \"outputs\": [\"dist/**\"]\n    },\n    \"generate\": {\n      \"dependsOn\": [\"^build\"],\n      \"outputs\": [\"src/gen/**\"]\n    },\n    \"test\": {\n      \"dependsOn\": [\"build\"],\n      \"cache\": false\n    },\n    \"format\": {},\n    \"license-header\": {\n      \"dependsOn\": [\"generate\"]\n    },\n    \"lint\": {\n      \"dependsOn\": [\"format\", \"^build\", \"generate\"]\n    },\n    \"attw\": {\n      \"dependsOn\": [\"build\"]\n    },\n    \"//#format\": {\n      \"inputs\": [\"$TURBO_DEFAULT$\", \"!packages/**\", \"package-lock.json\"]\n    },\n    \"//#license-header\": {\n      \"inputs\": [\"$TURBO_DEFAULT$\", \"!packages/**\"]\n    },\n    \"//#lint\": {\n      \"dependsOn\": [\"format\"],\n      \"inputs\": [\"$TURBO_DEFAULT$\", \"!packages/**\", \"package-lock.json\"]\n    }\n  }\n}\n"
  }
]